Version 1.22.0-dev.3.0
Merge commit '384d35240d34792e8f370dd3e566cebab53d0863' into dev
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e3c1bc8..d24dffa 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,16 +1,35 @@
## 1.22.0
+### Language
+
+ * The `assert()` statement has been expanded to support an optional second
+ `message` argument (SDK issue [27342](https://github.com/dart-lang/sdk/issues/27342)).
+
+ The message is displayed if the assert fails. It can be any object, and it
+ is accessible as `AssertionError.message`. It can be used to provide more
+ user friendly exception outputs. As an example, the following assert:
+
+ ```dart
+ assert(configFile != null, "Tool config missing. Please see https://goo.gl/k8iAi for details.");
+ ```
+
+ would produce the following exception output:
+
+ ```
+ Unhandled exception:
+ 'file:///Users/mit/tmp/tool/bin/main.dart': Failed assertion: line 9 pos 10:
+ 'configFile != null': Tool config missing. Please see https://goo.gl/k8iAi for details.
+ #0 _AssertionError._doThrowNew (dart:core-patch/errors_patch.dart:33)
+ #1 _AssertionError._throwNew (dart:core-patch/errors_patch.dart:29)
+ #2 main (file:///Users/mit/tmp/tool/bin/main.dart:9:10)
+ ```
+
### Tool changes
* Dart2Js
* Remove support for (long-time deprecated) mixin typedefs.
-* Dart Dev Compiler
-
- * Support messages in `assert()` statements. (SDK issue
- [27342](https://github.com/dart-lang/sdk/issues/27342))
-
* Pub
* Avoid using a barback asset server for executables unless they actually use
diff --git a/docs/language/dartLangSpec.tex b/docs/language/dartLangSpec.tex
index 44e846c..f2fee9d 100644
--- a/docs/language/dartLangSpec.tex
+++ b/docs/language/dartLangSpec.tex
@@ -1781,9 +1781,8 @@
The scope of the \EXTENDS{} and \WITH{} clauses of a class $C$ is the type-parameter scope of $C$.
\LMHash{}
-%It is a compile-time error if the \EXTENDS{} clause of a class $C$ includes a type expression that does not denote a class available in the lexical scope of $C$.
-It is a compile-time error if the \EXTENDS{} clause of a class $C$ specifies an enumerated type (\ref{enums}), a malformed type or a deferred type (\ref{staticTypes}) as a superclass.
-% too strict? Do we e want extends List<Undeclared> to work as List<dynamic>?
+It is a compile-time error if the \EXTENDS{} clause of a class $C$ specifies a type variable (\ref{generics}), a type alias (\ref{typedef}), an enumerated type (\ref{enums}), a malformed type, or a deferred type (\ref{staticTypes}) as a superclass.
+It is a compile-time error if the \EXTENDS{} clause of a class $C$ specifies type \DYNAMIC{} as a superinterface.
\commentary{ The type parameters of a generic class are available in the lexical scope of the superclass clause, potentially shadowing classes in the surrounding scope. The following code is therefore illegal and should cause a compile-time error:
}
@@ -1917,7 +1916,9 @@
The scope of the \IMPLEMENTS{} clause of a class $C$ is the type-parameter scope of $C$.
\LMHash{}
-It is a compile-time error if the \IMPLEMENTS{} clause of a class $C$ specifies a type variable as a superinterface. It is a compile-time error if the \IMPLEMENTS{} clause of a class $C$ specifies an enumerated type (\ref{enums}), a malformed type or deferred type (\ref{staticTypes}) as a superinterface. It is a compile-time error if the \IMPLEMENTS{} clause of a class $C$ specifies type \DYNAMIC{} as a superinterface. It is a compile-time error if the \IMPLEMENTS{} clause of a class $C$ specifies a type $T$ as a superinterface more than once.
+It is a compile-time error if the \IMPLEMENTS{} clause of a class $C$ specifies a type variable (\ref{generics}), a type alias (\ref{typedef}), an enumerated type (\ref{enums}), a malformed type, or a deferred type (\ref{staticTypes}) as a superinterface.
+It is a compile-time error if the \IMPLEMENTS{} clause of a class $C$ specifies type \DYNAMIC{} as a superinterface.
+It is a compile-time error if the \IMPLEMENTS{} clause of a class $C$ specifies a type $T$ as a superinterface more than once.
It is a compile-time error if the superclass of a class $C$ is specified as a superinterface of $C$.
\rationale{
@@ -2090,8 +2091,10 @@
\LMLabel{mixinApplication}
\LMHash{}
-A mixin may be applied to a superclass, yielding a new class. Mixin application occurs when a mixin is mixed into a class declaration via its \WITH{} clause. The mixin application may be used to extend a class per section (\ref{classes}); alternately, a class may be defined as a mixin application as described in this section. It is a compile-time error if the \WITH{} clause of a mixin application $C$ includes a deferred type expression.
-
+A mixin may be applied to a superclass, yielding a new class.
+Mixin application occurs when a mixin is mixed into a class declaration via its \WITH{} clause.
+The mixin application may be used to extend a class per section (\ref{classes}); alternately, a class may be defined as a mixin application as described in this section.
+It is a compile-time error if the \WITH{} clause of a mixin application $C$ includes a type variable (\ref{generics}), a type alias (\ref{typedef}), an enumerated type (\ref{enums}), a malformed type, or a deferred type (\ref{staticTypes}).
\begin{grammar}
{\bf mixinApplicationClass:}
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index 7751fb6..5ee2afd 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -678,6 +678,19 @@
}
/**
+ * Return the [nd.AnalysisDriver] for the "innermost" context whose associated
+ * folder is or contains the given path. ("innermost" refers to the nesting
+ * of contexts, so if there is a context for path /foo and a context for
+ * path /foo/bar, then the innermost context containing /foo/bar/baz.dart is
+ * the context for /foo/bar.)
+ *
+ * If no context contains the given path, `null` is returned.
+ */
+ nd.AnalysisDriver getContainingDriver(String path) {
+ return contextManager.getDriverFor(path);
+ }
+
+ /**
* Return the primary [ContextSourcePair] representing the given [path].
*
* The [AnalysisContext] of this pair will be the context that explicitly
diff --git a/pkg/analysis_server/lib/src/computer/new_notifications.dart b/pkg/analysis_server/lib/src/computer/new_notifications.dart
index 2d575a9..1ca3636 100644
--- a/pkg/analysis_server/lib/src/computer/new_notifications.dart
+++ b/pkg/analysis_server/lib/src/computer/new_notifications.dart
@@ -16,7 +16,7 @@
var unit = result.unit;
if (unit != null) {
NavigationCollectorImpl collector = new NavigationCollectorImpl();
- computeSimpleDartNavigation(collector, unit);
+ computeDartNavigation(collector, unit, null, null);
collector.createRegions();
var params = new protocol.AnalysisNavigationParams(
result.path, collector.regions, collector.targets, collector.files);
diff --git a/pkg/analysis_server/lib/src/domain_analysis.dart b/pkg/analysis_server/lib/src/domain_analysis.dart
index 5066533..424815d 100644
--- a/pkg/analysis_server/lib/src/domain_analysis.dart
+++ b/pkg/analysis_server/lib/src/domain_analysis.dart
@@ -13,6 +13,7 @@
import 'package:analysis_server/src/constants.dart';
import 'package:analysis_server/src/context_manager.dart';
import 'package:analysis_server/src/domains/analysis/navigation.dart';
+import 'package:analysis_server/src/domains/analysis/navigation_dart.dart';
import 'package:analysis_server/src/operation/operation_analysis.dart'
show NavigationOperation, OccurrencesOperation;
import 'package:analysis_server/src/protocol/protocol_internal.dart';
@@ -147,26 +148,24 @@
var params = new AnalysisGetNavigationParams.fromRequest(request);
String file = params.file;
- void send(CompilationUnit unit) {
- if (unit == null) {
+ if (server.options.enableNewAnalysisDriver) {
+ AnalysisDriver driver = server.getContainingDriver(file);
+ if (driver == null) {
server.sendResponse(new Response.getNavigationInvalidFile(request));
} else {
- CompilationUnitElement unitElement = unit.element;
- NavigationCollectorImpl collector = computeNavigation(
- server,
- unitElement.context,
- unitElement.source,
- params.offset,
- params.length);
- server.sendResponse(new AnalysisGetNavigationResult(
- collector.files, collector.targets, collector.regions)
- .toResponse(request.id));
+ AnalysisResult result = await server.getAnalysisResult(file);
+ CompilationUnit unit = result?.unit;
+ if (unit == null || !result.exists) {
+ server.sendResponse(new Response.getNavigationInvalidFile(request));
+ } else {
+ NavigationCollectorImpl collector = new NavigationCollectorImpl();
+ computeDartNavigation(collector, unit, params.offset, params.length);
+ collector.createRegions();
+ server.sendResponse(new AnalysisGetNavigationResult(
+ collector.files, collector.targets, collector.regions)
+ .toResponse(request.id));
+ }
}
- }
-
- if (server.options.enableNewAnalysisDriver) {
- AnalysisResult result = await server.getAnalysisResult(file);
- send(result?.unit);
return;
}
@@ -179,7 +178,20 @@
switch (reason) {
case AnalysisDoneReason.COMPLETE:
CompilationUnit unit = await server.getResolvedCompilationUnit(file);
- send(unit);
+ if (unit == null) {
+ server.sendResponse(new Response.getNavigationInvalidFile(request));
+ } else {
+ CompilationUnitElement unitElement = unit.element;
+ NavigationCollectorImpl collector = computeNavigation(
+ server,
+ unitElement.context,
+ unitElement.source,
+ params.offset,
+ params.length);
+ server.sendResponse(new AnalysisGetNavigationResult(
+ collector.files, collector.targets, collector.regions)
+ .toResponse(request.id));
+ }
break;
case AnalysisDoneReason.CONTEXT_REMOVED:
// The active contexts have changed, so try again.
diff --git a/pkg/analysis_server/lib/src/domains/analysis/navigation_dart.dart b/pkg/analysis_server/lib/src/domains/analysis/navigation_dart.dart
index 1ae3193..63f10df 100644
--- a/pkg/analysis_server/lib/src/domains/analysis/navigation_dart.dart
+++ b/pkg/analysis_server/lib/src/domains/analysis/navigation_dart.dart
@@ -15,16 +15,31 @@
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
-NavigationCollector computeSimpleDartNavigation(
- NavigationCollector collector, CompilationUnit unit) {
+NavigationCollector computeDartNavigation(NavigationCollector collector,
+ CompilationUnit unit, int offset, int length) {
_DartNavigationCollector dartCollector =
new _DartNavigationCollector(collector);
_DartNavigationComputerVisitor visitor =
new _DartNavigationComputerVisitor(dartCollector);
- unit.accept(visitor);
+ if (offset == null || length == null) {
+ unit.accept(visitor);
+ } else {
+ AstNode node = _getNodeForRange(unit, offset, length);
+ node?.accept(visitor);
+ }
return collector;
}
+AstNode _getNodeForRange(CompilationUnit unit, int offset, int length) {
+ AstNode node = new NodeLocator(offset, offset + length).searchWithin(unit);
+ for (AstNode n = node; n != null; n = n.parent) {
+ if (n is Directive) {
+ return n;
+ }
+ }
+ return node;
+}
+
/**
* A computer for navigation regions in a Dart [CompilationUnit].
*/
@@ -37,30 +52,10 @@
CompilationUnit unit =
context.getResolvedCompilationUnit2(source, libraries.first);
if (unit != null) {
- _DartNavigationCollector dartCollector =
- new _DartNavigationCollector(collector);
- _DartNavigationComputerVisitor visitor =
- new _DartNavigationComputerVisitor(dartCollector);
- if (offset == null || length == null) {
- unit.accept(visitor);
- } else {
- AstNode node = _getNodeForRange(unit, offset, length);
- node?.accept(visitor);
- }
+ computeDartNavigation(collector, unit, offset, length);
}
}
}
-
- static AstNode _getNodeForRange(
- CompilationUnit unit, int offset, int length) {
- AstNode node = new NodeLocator(offset, offset + length).searchWithin(unit);
- for (AstNode n = node; n != null; n = n.parent) {
- if (n is Directive) {
- return n;
- }
- }
- return node;
- }
}
/**
diff --git a/pkg/analysis_server/test/analysis/get_navigation_test.dart b/pkg/analysis_server/test/analysis/get_navigation_test.dart
index 5e262a7..085659e 100644
--- a/pkg/analysis_server/test/analysis/get_navigation_test.dart
+++ b/pkg/analysis_server/test/analysis/get_navigation_test.dart
@@ -15,6 +15,7 @@
main() {
defineReflectiveSuite(() {
defineReflectiveTests(GetNavigationTest);
+ defineReflectiveTests(GetNavigationTest_Driver);
});
}
@@ -248,3 +249,13 @@
regions = result.regions;
}
}
+
+@reflectiveTest
+class GetNavigationTest_Driver extends GetNavigationTest {
+ @override
+ void setUp() {
+ enableNewAnalysisDriver = true;
+ generateSummaryFiles = true;
+ super.setUp();
+ }
+}
diff --git a/pkg/analysis_server/test/context_manager_test.dart b/pkg/analysis_server/test/context_manager_test.dart
index db3bf03..ded3532 100644
--- a/pkg/analysis_server/test/context_manager_test.dart
+++ b/pkg/analysis_server/test/context_manager_test.dart
@@ -2136,6 +2136,46 @@
expect(lints[0].name, 'camel_case_types');
}
+ test_analysis_options_include_package() async {
+ // Create files.
+ String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]);
+ newFile([libPath, 'main.dart']);
+ String sdkExtPath = newFolder([projPath, 'sdk_ext']);
+ newFile([sdkExtPath, 'entry.dart']);
+ String sdkExtSrcPath = newFolder([projPath, 'sdk_ext', 'src']);
+ newFile([sdkExtSrcPath, 'part.dart']);
+ // Setup package
+ String booLibPosixPath = '/my/pkg/boo/lib';
+ newFile(
+ [booLibPosixPath, 'other_options.yaml'],
+ r'''
+analyzer:
+ language:
+ enableStrictCallChecks: true
+ errors:
+ unused_local_variable: false
+linter:
+ rules:
+ - camel_case_types
+''');
+ // Setup analysis options file which includes another options file.
+ newFile([projPath, ContextManagerImpl.PACKAGE_SPEC_NAME],
+ 'boo:$booLibPosixPath\n');
+ newFile(
+ [projPath, optionsFileName],
+ r'''
+include: package:boo/other_options.yaml
+''');
+ // Setup context.
+ manager.setRoots(<String>[projPath], <String>[], <String, String>{});
+ await pumpEventQueue();
+ // Verify options were set.
+ expect(analysisOptions.enableStrictCallChecks, isTrue);
+ expect(errorProcessors, hasLength(1));
+ expect(lints, hasLength(1));
+ expect(lints[0].name, 'camel_case_types');
+ }
+
test_analysis_options_parse_failure() async {
// Create files.
String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]);
diff --git a/pkg/analyzer/lib/src/command_line/arguments.dart b/pkg/analyzer/lib/src/command_line/arguments.dart
index f85a34e..5ea958e 100644
--- a/pkg/analyzer/lib/src/command_line/arguments.dart
+++ b/pkg/analyzer/lib/src/command_line/arguments.dart
@@ -103,25 +103,46 @@
* Add the standard flags and options to the given [parser]. The standard flags
* are those that are typically used to control the way in which the code is
* analyzed.
+ *
+ * TODO(danrubel) Update DDC to support all the options defined in this method
+ * then remove the [ddc] named argument from this method.
*/
-void defineAnalysisArguments(ArgParser parser, {bool hide: true}) {
- defineDDCAnalysisArguments(parser, hide: hide);
+void defineAnalysisArguments(ArgParser parser, {bool hide: true, ddc: false}) {
+ parser.addOption(defineVariableOption,
+ abbr: 'D',
+ allowMultiple: true,
+ help: 'Define environment variables. For example, "-Dfoo=bar" defines an '
+ 'environment variable named "foo" whose value is "bar".');
+
+ parser.addOption(sdkPathOption, help: 'The path to the Dart SDK.');
+ parser.addOption(sdkSummaryPathOption,
+ help: 'The path to the Dart SDK summary file.', hide: hide);
parser.addOption(analysisOptionsFileOption,
- help: 'Path to an analysis options file.');
+ help: 'Path to an analysis options file.', hide: ddc);
+
+ parser.addOption(packageRootOption,
+ abbr: 'p',
+ help: 'The path to a package root directory (deprecated). '
+ 'This option cannot be used with --packages.');
parser.addOption(packagesOption,
help: 'The path to the package resolution configuration file, which '
'supplies a mapping of package names to paths. This option cannot be '
- 'used with --package-root.');
+ 'used with --package-root.',
+ hide: ddc);
parser.addFlag(strongModeFlag,
- help: 'Enable strong static checks (https://goo.gl/DqcBsw)');
+ help: 'Enable strong static checks (https://goo.gl/DqcBsw)',
+ defaultsTo: ddc,
+ hide: ddc);
parser.addFlag(noImplicitCastsFlag,
negatable: false,
- help: 'Disable implicit casts in strong mode (https://goo.gl/cTLz40)');
+ help: 'Disable implicit casts in strong mode (https://goo.gl/cTLz40)',
+ hide: ddc);
parser.addFlag(noImplicitDynamicFlag,
negatable: false,
- help: 'Disable implicit dynamic (https://goo.gl/m0UgXD)');
+ help: 'Disable implicit dynamic (https://goo.gl/m0UgXD)',
+ hide: ddc);
//
// Hidden flags and options.
//
@@ -129,51 +150,29 @@
// help: 'Enable support for null-aware operators (DEP 9).',
// defaultsTo: false,
// negatable: false,
-// hide: hide);
+// hide: hide || ddc);
parser.addFlag(enableStrictCallChecksFlag,
help: 'Fix issue 21938.',
defaultsTo: false,
negatable: false,
- hide: hide);
+ hide: hide || ddc);
parser.addFlag(enableInitializingFormalAccessFlag,
help:
'Enable support for allowing access to field formal parameters in a '
'constructor\'s initializer list',
defaultsTo: false,
negatable: false,
- hide: hide);
+ hide: hide || ddc);
parser.addFlag(enableSuperInMixinFlag,
help: 'Relax restrictions on mixins (DEP 34).',
defaultsTo: false,
negatable: false,
- hide: hide);
+ hide: hide || ddc);
// parser.addFlag('enable_type_checks',
// help: 'Check types in constant evaluation.',
// defaultsTo: false,
// negatable: false,
-// hide: hide);
-}
-
-/**
- * Add the DDC analysis flags and options to the given [parser].
- *
- * TODO(danrubel) Update DDC to support all the options defined in
- * the [defineAnalysisOptions] method above, then have DDC call that method
- * and remove this method.
- */
-void defineDDCAnalysisArguments(ArgParser parser, {bool hide: true}) {
- parser.addOption(defineVariableOption,
- abbr: 'D',
- allowMultiple: true,
- help: 'Define environment variables. For example, "-Dfoo=bar" defines an '
- 'environment variable named "foo" whose value is "bar".');
- parser.addOption(sdkPathOption, help: 'The path to the Dart SDK.');
- parser.addOption(sdkSummaryPathOption,
- help: 'The path to the Dart SDK summary file.', hide: hide);
- parser.addOption(packageRootOption,
- abbr: 'p',
- help: 'The path to a package root directory (deprecated). '
- 'This option cannot be used with --packages.');
+// hide: hide || ddc);
}
/**
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index a6bb7fa..ef28cb2 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -30,6 +30,7 @@
import 'package:analyzer/src/summary/package_bundle_reader.dart';
import 'package:analyzer/src/task/dart.dart' show COMPILATION_UNIT_ELEMENT;
import 'package:analyzer/task/dart.dart' show LibrarySpecificUnit;
+import 'package:meta/meta.dart';
/**
* This class computes [AnalysisResult]s for Dart files.
@@ -219,6 +220,8 @@
*/
Search _search;
+ AnalysisDriverTestView _testView;
+
/**
* Create a new instance of [AnalysisDriver].
*
@@ -234,6 +237,7 @@
SourceFactory sourceFactory,
this._analysisOptions)
: _sourceFactory = sourceFactory.clone() {
+ _testView = new AnalysisDriverTestView(this);
_fillSalt();
_sdkBundle = sourceFactory.dartSdk.getLinkedBundle();
_fsState = new FileSystemState(
@@ -348,6 +352,9 @@
*/
Stream<AnalysisStatus> get status => _statusSupport.stream;
+ @visibleForTesting
+ AnalysisDriverTestView get test => _testView;
+
/**
* Return the priority of work that the driver needs to perform.
*/
@@ -841,6 +848,7 @@
_sourceFactory,
file.path,
file.uri,
+ file.exists,
content,
file.contentHash,
file.lineInfo,
@@ -907,7 +915,11 @@
// Verify all changed files one at a time.
if (_changedFiles.isNotEmpty) {
String path = _removeFirst(_changedFiles);
- _verifyApiSignature(path);
+ // If the file has not been accessed yet, we either will eventually read
+ // it later while analyzing one of the added files, or don't need it.
+ if (_fsState.knownFilePaths.contains(path)) {
+ _verifyApiSignature(path);
+ }
return;
}
@@ -1256,6 +1268,15 @@
}
}
+@visibleForTesting
+class AnalysisDriverTestView {
+ final AnalysisDriver driver;
+
+ AnalysisDriverTestView(this.driver);
+
+ Set<String> get filesToAnalyze => driver._filesToAnalyze;
+}
+
/**
* The result of analyzing of a single file.
*
@@ -1291,6 +1312,11 @@
final Uri uri;
/**
+ * Return `true` if the file exists.
+ */
+ final bool exists;
+
+ /**
* The content of the file that was scanned, parsed and resolved.
*/
final String content;
@@ -1325,6 +1351,7 @@
this.sourceFactory,
this.path,
this.uri,
+ this.exists,
this.content,
this.contentHash,
this.lineInfo,
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
index 04e2fe9..0bc2d9a 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
@@ -362,6 +362,9 @@
provider.updateFile(b, 'var B = 1.2;');
driver.changeFile(b);
+ // "b" is not an added file, so it is not scheduled for analysis.
+ expect(driver.test.filesToAnalyze, isEmpty);
+
// While "b" is not analyzed explicitly, it is analyzed implicitly.
// The change causes "a" to be reanalyzed.
await _waitForIdle();
@@ -372,6 +375,28 @@
}
}
+ test_changeFile_notUsed() async {
+ var a = _p('/test/lib/a.dart');
+ var b = _p('/other/b.dart');
+ provider.newFile(a, '');
+ provider.newFile(b, 'class B1 {}');
+
+ driver.addFile(a);
+
+ await _waitForIdle();
+ allResults.clear();
+
+ // Change "b" and notify.
+ // Nothing depends on "b", so nothing is analyzed.
+ provider.updateFile(b, 'class B2 {}');
+ driver.changeFile(b);
+ await _waitForIdle();
+ expect(allResults, isEmpty);
+
+ // This should not add "b" to the file state.
+ expect(driver.fsState.knownFilePaths, isNot(contains(b)));
+ }
+
test_changeFile_selfConsistent() async {
var a = _p('/test/lib/a.dart');
var b = _p('/test/lib/b.dart');
@@ -455,6 +480,9 @@
// Notify the driver about the change.
driver.changeFile(testFile);
+ // The file was added, so it is scheduled for analysis.
+ expect(driver.test.filesToAnalyze, contains(testFile));
+
// We get a new result.
{
await _waitForIdle();
@@ -570,6 +598,7 @@
AnalysisResult result = await driver.getResult(testFile);
expect(result.path, testFile);
expect(result.uri.toString(), 'package:test/test.dart');
+ expect(result.exists, isTrue);
expect(result.content, content);
expect(result.contentHash, _md5(content));
expect(result.unit, isNotNull);
@@ -605,6 +634,16 @@
expect(result.errors, isEmpty);
}
+ test_getResult_doesNotExist() async {
+ var a = _p('/test/lib/a.dart');
+
+ AnalysisResult result = await driver.getResult(a);
+ expect(result.path, a);
+ expect(result.uri.toString(), 'package:test/a.dart');
+ expect(result.exists, isFalse);
+ expect(result.content, '');
+ }
+
test_getResult_errors() async {
String content = 'main() { int vv; }';
addTestFile(content, priority: true);
diff --git a/pkg/analyzer_cli/lib/src/options.dart b/pkg/analyzer_cli/lib/src/options.dart
index 2b75a64..c83cffc 100644
--- a/pkg/analyzer_cli/lib/src/options.dart
+++ b/pkg/analyzer_cli/lib/src/options.dart
@@ -8,6 +8,7 @@
import 'package:analyzer/file_system/physical_file_system.dart';
import 'package:analyzer/src/command_line/arguments.dart';
+import 'package:analyzer/src/context/builder.dart';
import 'package:analyzer_cli/src/driver.dart';
import 'package:args/args.dart';
import 'package:cli_util/cli_util.dart' show getSdkDir;
@@ -32,9 +33,6 @@
/// Analyzer commandline configuration options.
class CommandLineOptions {
- /// The path to an analysis options file
- final String analysisOptionsFile;
-
/// The path to output analysis results when in build mode.
final String buildAnalysisOutput;
@@ -67,15 +65,15 @@
/// Whether to suppress a nonzero exit code in build mode.
final bool buildSuppressExitCode;
+ /// The options defining the context in which analysis is performed.
+ final ContextBuilderOptions contextBuilderOptions;
+
/// The path to the dart SDK.
String dartSdkPath;
/// The path to the dart SDK summary file.
String dartSdkSummaryPath;
- /// A table mapping the names of defined variables to their values.
- final Map<String, String> definedVariables;
-
/// Whether to disable cache flushing. This option can improve analysis
/// speed at the expense of memory usage. It may also be useful for working
/// around bugs.
@@ -90,13 +88,6 @@
/// Whether to enable null-aware operators (DEP 9).
final bool enableNullAwareOperators;
- /// Whether to strictly follow the specification when generating warnings on
- /// "call" methods (fixes dartbug.com/21938).
- final bool enableStrictCallChecks;
-
- /// Whether to relax restrictions on mixins (DEP 34).
- final bool enableSuperMixins;
-
/// Whether to treat type mismatches found during constant evaluation as
/// errors.
final bool enableTypeChecks;
@@ -116,12 +107,6 @@
/// Whether to use machine format for error display
final bool machineFormat;
- /// The path to the package root
- final String packageRootPath;
-
- /// The path to a `.packages` configuration file
- final String packageConfigPath;
-
/// The path to a file to write a performance log.
/// (Or null if not enabled.)
final String perfReport;
@@ -157,8 +142,7 @@
final bool lintsAreFatal;
/// Initialize options from the given parsed [args].
- CommandLineOptions._fromArgs(
- ArgResults args, Map<String, String> definedVariables)
+ CommandLineOptions._fromArgs(ArgResults args)
: buildAnalysisOutput = args['build-analysis-output'],
buildMode = args['build-mode'],
buildModePersistentWorker = args['persistent_worker'],
@@ -170,24 +154,19 @@
buildSummaryOutput = args['build-summary-output'],
buildSummaryOutputSemantic = args['build-summary-output-semantic'],
buildSuppressExitCode = args['build-suppress-exit-code'],
+ contextBuilderOptions = createContextBuilderOptions(args),
dartSdkPath = args['dart-sdk'],
dartSdkSummaryPath = args['dart-sdk-summary'],
- definedVariables = definedVariables,
- analysisOptionsFile = args['options'],
disableCacheFlushing = args['disable-cache-flushing'],
disableHints = args['no-hints'],
displayVersion = args['version'],
enableNullAwareOperators = args['enable-null-aware-operators'],
- enableStrictCallChecks = args['enable-strict-call-checks'],
- enableSuperMixins = args['supermixin'],
enableTypeChecks = args['enable_type_checks'],
hintsAreFatal = args['fatal-hints'],
ignoreUnrecognizedFlags = args['ignore-unrecognized-flags'],
lints = args['lints'],
log = args['log'],
machineFormat = args['machine'] || args['format'] == 'machine',
- packageConfigPath = args['packages'],
- packageRootPath = args['package-root'],
perfReport = args['x-perf-report'],
shouldBatch = args['batch'],
showPackageWarnings = args['show-package-warnings'] ||
@@ -202,6 +181,30 @@
implicitDynamic = !args['no-implicit-dynamic'],
lintsAreFatal = args['fatal-lints'];
+ /// The path to an analysis options file
+ String get analysisOptionsFile =>
+ contextBuilderOptions.defaultAnalysisOptionsFilePath;
+
+ /// A table mapping the names of defined variables to their values.
+ Map<String, String> get definedVariables =>
+ contextBuilderOptions.declaredVariables;
+
+ /// Whether to strictly follow the specification when generating warnings on
+ /// "call" methods (fixes dartbug.com/21938).
+ bool get enableStrictCallChecks =>
+ contextBuilderOptions.defaultOptions.enableStrictCallChecks;
+
+ /// Whether to relax restrictions on mixins (DEP 34).
+ bool get enableSuperMixins =>
+ contextBuilderOptions.defaultOptions.enableSuperMixins;
+
+ /// The path to the package root
+ String get packageRootPath =>
+ contextBuilderOptions.defaultPackagesDirectoryPath;
+
+ /// The path to a `.packages` configuration file
+ String get packageConfigPath => contextBuilderOptions.defaultPackageFilePath;
+
/// Parse [args] into [CommandLineOptions] describing the specified
/// analyzer options. In case of a format error, calls [printAndFail], which
/// by default prints an error message to stderr and exits.
@@ -454,8 +457,6 @@
// TODO(scheglov) https://code.google.com/p/dart/issues/detail?id=11061
args =
args.map((String arg) => arg == '-batch' ? '--batch' : arg).toList();
- Map<String, String> definedVariables = <String, String>{};
- args = extractDefinedVariables(args, definedVariables);
if (args.contains('--$ignoreUnrecognizedFlagsFlag')) {
args = filterUnknownArguments(args, parser);
}
@@ -479,7 +480,7 @@
'option. Got: $args');
return null; // Only reachable in testing.
}
- return new CommandLineOptions._fromArgs(results, definedVariables);
+ return new CommandLineOptions._fromArgs(results);
}
// Help requests.
@@ -515,7 +516,7 @@
return null; // Only reachable in testing.
}
}
- return new CommandLineOptions._fromArgs(results, definedVariables);
+ return new CommandLineOptions._fromArgs(results);
} on FormatException catch (e) {
errorSink.writeln(e.message);
_showUsage(parser);
diff --git a/pkg/analyzer_cli/test/options_test.dart b/pkg/analyzer_cli/test/options_test.dart
index 0a34dfc..c0ca301 100644
--- a/pkg/analyzer_cli/test/options_test.dart
+++ b/pkg/analyzer_cli/test/options_test.dart
@@ -55,11 +55,9 @@
test('defined variables', () {
CommandLineOptions options = CommandLineOptions
- .parse(['--dart-sdk', '.', '-Dfoo=bar', '-Da', 'b', 'foo.dart']);
+ .parse(['--dart-sdk', '.', '-Dfoo=bar', 'foo.dart']);
expect(options.definedVariables['foo'], equals('bar'));
expect(options.definedVariables['bar'], isNull);
- expect(options.definedVariables['a'], equals('b'));
- expect(options.definedVariables['b'], isNull);
});
test('disable cache flushing', () {
diff --git a/pkg/compiler/lib/src/common/backend_api.dart b/pkg/compiler/lib/src/common/backend_api.dart
index aef574d..e0c396c 100644
--- a/pkg/compiler/lib/src/common/backend_api.dart
+++ b/pkg/compiler/lib/src/common/backend_api.dart
@@ -103,7 +103,7 @@
}
/// Generates the output and returns the total size of the generated code.
- int assembleProgram();
+ int assembleProgram(ClosedWorld closedWorld);
List<CompilerTask> get tasks;
@@ -311,7 +311,10 @@
/// Called when the compiler starts running the codegen enqueuer. The
/// [WorldImpact] of enabled backend features is returned.
- WorldImpact onCodegenStart() => const WorldImpact();
+ WorldImpact onCodegenStart(ClosedWorld closedWorld) => const WorldImpact();
+
+ /// Called when code generation has been completed.
+ void onCodegenEnd() {}
// Does this element belong in the output
bool shouldOutput(Element element) => true;
@@ -418,6 +421,7 @@
ClassElement get indexableImplementation;
ClassElement get mutableIndexableImplementation;
ClassElement get indexingBehaviorImplementation;
+ ClassElement get interceptorImplementation;
bool isDefaultEqualityImplementation(Element element);
bool isInterceptorClass(ClassElement cls);
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index d3e98c0..07d9c89 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -78,7 +78,7 @@
WorldImpactBuilder,
WorldImpactBuilderImpl;
import 'util/util.dart' show Link, Setlet;
-import 'world.dart' show ClosedWorld, ClosedWorldRefiner, OpenWorld, WorldImpl;
+import 'world.dart' show ClosedWorld, ClosedWorldRefiner, WorldImpl;
typedef Backend MakeBackendFuncion(Compiler compiler);
@@ -89,7 +89,6 @@
Measurer get measurer;
final IdGenerator idGenerator = new IdGenerator();
- WorldImpl get _world => resolverWorld.openWorld;
Types types;
_CompilerCoreTypes _coreTypes;
CompilerDiagnosticReporter _reporter;
@@ -130,8 +129,6 @@
ResolvedUriTranslator get resolvedUriTranslator;
- Tracer tracer;
-
LibraryElement mainApp;
FunctionElement mainFunction;
@@ -217,7 +214,6 @@
// make its field final.
_coreTypes = new _CompilerCoreTypes(_resolution, reporter);
types = new Types(_resolution);
- tracer = new Tracer(this, this.outputProvider);
if (options.verbose) {
progress = new Stopwatch()..start();
@@ -279,13 +275,6 @@
tasks.addAll(backend.tasks);
}
- /// The closed world after resolution and inference.
- ClosedWorld get closedWorld {
- assert(invariant(CURRENT_ELEMENT_SPANNABLE, _world.isClosed,
- message: "Closed world not computed yet."));
- return _world;
- }
-
/// Creates the backend.
///
/// Override this to mock the backend for testing.
@@ -344,7 +333,6 @@
return new Future.sync(() => runInternal(uri))
.catchError((error) => _reporter.onError(uri, error))
.whenComplete(() {
- tracer.close();
measurer.stopWallClock();
}).then((_) {
return !compilationFailed;
@@ -708,6 +696,9 @@
assert(mainFunction != null);
ClosedWorldRefiner closedWorldRefiner = closeResolution();
+ // TODO(johnniwinther): Make [ClosedWorld] a property of
+ // [ClosedWorldRefiner].
+ ClosedWorld closedWorld = resolverWorld.closedWorldForTesting;
reporter.log('Inferring types...');
globalInference.runGlobalTypeInference(
@@ -720,7 +711,7 @@
reporter.log('Compiling...');
phase = PHASE_COMPILING;
- enqueuer.codegen.applyImpact(backend.onCodegenStart());
+ enqueuer.codegen.applyImpact(backend.onCodegenStart(closedWorld));
if (compileAll) {
libraryLoader.libraries.forEach((LibraryElement library) {
enqueuer.codegen.applyImpact(computeImpactForLibrary(library));
@@ -730,14 +721,14 @@
onProgress: showCodegenProgress);
enqueuer.codegen.logSummary(reporter.log);
- int programSize = backend.assembleProgram();
+ int programSize = backend.assembleProgram(closedWorld);
if (options.dumpInfo) {
dumpInfoTask.reportSize(programSize);
dumpInfoTask.dumpInfo(closedWorld);
}
- backend.sourceInformationStrategy.onComplete();
+ backend.onCodegenEnd();
checkQueues();
});
diff --git a/pkg/compiler/lib/src/elements/elements.dart b/pkg/compiler/lib/src/elements/elements.dart
index 9fef687..95acc7b 100644
--- a/pkg/compiler/lib/src/elements/elements.dart
+++ b/pkg/compiler/lib/src/elements/elements.dart
@@ -1664,7 +1664,7 @@
abstract class JumpTarget extends Local {
Node get statement;
int get nestingLevel;
- Link<LabelDefinition> get labels;
+ List<LabelDefinition> get labels;
bool get isTarget;
bool get isBreakTarget;
diff --git a/pkg/compiler/lib/src/elements/modelx.dart b/pkg/compiler/lib/src/elements/modelx.dart
index b479367..c2d2e75 100644
--- a/pkg/compiler/lib/src/elements/modelx.dart
+++ b/pkg/compiler/lib/src/elements/modelx.dart
@@ -3209,7 +3209,7 @@
final ExecutableElement executableContext;
final Node statement;
final int nestingLevel;
- Link<LabelDefinition> labels = const Link<LabelDefinition>();
+ List<LabelDefinition> labels = <LabelDefinition>[];
bool isBreakTarget = false;
bool isContinueTarget = false;
@@ -3223,7 +3223,7 @@
LabelDefinition addLabel(Label label, String labelName) {
LabelDefinition result = new LabelDefinitionX(label, labelName, this);
- labels = labels.prepend(result);
+ labels.add(result);
return result;
}
diff --git a/pkg/compiler/lib/src/inferrer/inferrer_visitor.dart b/pkg/compiler/lib/src/inferrer/inferrer_visitor.dart
index 6a5d7f7..ef9fbfa 100644
--- a/pkg/compiler/lib/src/inferrer/inferrer_visitor.dart
+++ b/pkg/compiler/lib/src/inferrer/inferrer_visitor.dart
@@ -862,7 +862,7 @@
// The JavaScript backend may turn this literal into an integer at
// runtime.
return types.getConcreteTypeFor(
- computeTypeMask(compiler, constantSystem.createDouble(node.value)));
+ computeTypeMask(closedWorld, constantSystem.createDouble(node.value)));
}
T visitLiteralInt(LiteralInt node) {
@@ -870,7 +870,7 @@
// The JavaScript backend may turn this literal into a double at
// runtime.
return types.getConcreteTypeFor(
- computeTypeMask(compiler, constantSystem.createInt(node.value)));
+ computeTypeMask(closedWorld, constantSystem.createInt(node.value)));
}
T visitLiteralList(LiteralList node) {
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart b/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
index 1ac65fc..332e256 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
@@ -863,7 +863,7 @@
// Although we might find a better type, we have to keep
// the old type around to ensure that we get a complete view
// of the type graph and do not drop any flow edges.
- TypeMask refinedType = computeTypeMask(compiler, value);
+ TypeMask refinedType = computeTypeMask(closedWorld, value);
assert(TypeMask.assertIsNormalized(refinedType, closedWorld));
type = new NarrowTypeInformation(type, refinedType);
types.allocatedTypes.add(type);
diff --git a/pkg/compiler/lib/src/js_backend/backend.dart b/pkg/compiler/lib/src/js_backend/backend.dart
index f5018bf..fe066c7 100644
--- a/pkg/compiler/lib/src/js_backend/backend.dart
+++ b/pkg/compiler/lib/src/js_backend/backend.dart
@@ -45,6 +45,7 @@
import '../library_loader.dart' show LibraryLoader, LoadedLibraries;
import '../native/native.dart' as native;
import '../ssa/ssa.dart' show SsaFunctionCompiler;
+import '../tracer.dart';
import '../tree/tree.dart';
import '../types/types.dart';
import '../universe/call_structure.dart' show CallStructure;
@@ -88,7 +89,7 @@
abstract class FunctionCompiler {
/// Generates JavaScript code for `work.element`.
- jsAst.Fun compile(CodegenWorkItem work);
+ jsAst.Fun compile(CodegenWorkItem work, ClosedWorld closedWorld);
Iterable get tasks;
}
@@ -305,7 +306,7 @@
class JavaScriptBackend extends Backend {
String get patchVersion => emitter.patchVersion;
- bool get supportsReflection => emitter.emitter.supportsReflection;
+ bool get supportsReflection => emitter.supportsReflection;
final Annotations annotations;
@@ -343,7 +344,13 @@
bool needToInitializeIsolateAffinityTag = false;
bool needToInitializeDispatchProperty = false;
- final Namer namer;
+ Namer _namer;
+
+ Namer get namer {
+ assert(invariant(NO_LOCATION_SPANNABLE, _namer != null,
+ message: "Namer has not been created yet."));
+ return _namer;
+ }
/**
* A collection of selectors that must have a one shot interceptor
@@ -553,13 +560,14 @@
final JSFrontendAccess frontend;
+ Tracer tracer;
+
JavaScriptBackend(Compiler compiler,
{bool generateSourceMap: true,
bool useStartupEmitter: false,
bool useNewSourceInfo: false,
bool useKernel: false})
- : namer = determineNamer(compiler),
- oneShotInterceptors = new Map<jsAst.Name, Selector>(),
+ : oneShotInterceptors = new Map<jsAst.Name, Selector>(),
interceptedElements = new Map<String, Set<Element>>(),
rti = new _RuntimeTypes(compiler),
rtiEncoder = new _RuntimeTypesEncoder(compiler),
@@ -574,8 +582,8 @@
impacts = new BackendImpacts(compiler),
frontend = new JSFrontendAccess(compiler),
super(compiler) {
- emitter = new CodeEmitterTask(
- compiler, namer, generateSourceMap, useStartupEmitter);
+ emitter =
+ new CodeEmitterTask(compiler, generateSourceMap, useStartupEmitter);
typeVariableHandler = new TypeVariableHandler(compiler);
customElementsAnalysis = new CustomElementsAnalysis(this);
lookupMapAnalysis = new LookupMapAnalysis(this, reporter);
@@ -640,12 +648,12 @@
library == helpers.jsHelperLibrary;
}
- static Namer determineNamer(Compiler compiler) {
+ Namer determineNamer(ClosedWorld closedWorld) {
return compiler.options.enableMinification
? compiler.options.useFrequencyNamer
- ? new FrequencyBasedNamer(compiler)
- : new MinifyNamer(compiler)
- : new Namer(compiler);
+ ? new FrequencyBasedNamer(this, closedWorld)
+ : new MinifyNamer(this, closedWorld)
+ : new Namer(this, closedWorld);
}
/// The backend must *always* call this method when enqueuing an
@@ -893,8 +901,7 @@
if (elements.isEmpty) return false;
return elements.any((element) {
return selector.applies(element) &&
- (mask == null ||
- mask.canHit(element, selector, compiler.closedWorld));
+ (mask == null || mask.canHit(element, selector, _closedWorld));
});
}
@@ -950,11 +957,10 @@
}
Set<ClassElement> nativeSubclassesOfMixin(ClassElement mixin) {
- ClosedWorld closedWorld = compiler.closedWorld;
- Iterable<MixinApplicationElement> uses = closedWorld.mixinUsesOf(mixin);
+ Iterable<MixinApplicationElement> uses = _closedWorld.mixinUsesOf(mixin);
Set<ClassElement> result = null;
for (MixinApplicationElement use in uses) {
- closedWorld.forEachStrictSubclassOf(use, (ClassElement subclass) {
+ _closedWorld.forEachStrictSubclassOf(use, (ClassElement subclass) {
if (isNativeOrExtendsNative(subclass)) {
if (result == null) result = new Set<ClassElement>();
result.add(subclass);
@@ -1494,7 +1500,7 @@
}
}
- jsAst.Fun function = functionCompiler.compile(work);
+ jsAst.Fun function = functionCompiler.compile(work, _closedWorld);
if (function.sourceInformation == null) {
function = function.withSourceInformation(
sourceInformationStrategy.buildSourceMappedMarker());
@@ -1534,8 +1540,8 @@
return jsAst.prettyPrint(generatedCode[element], compiler);
}
- int assembleProgram() {
- int programSize = emitter.assembleProgram();
+ int assembleProgram(ClosedWorld closedWorld) {
+ int programSize = emitter.assembleProgram(namer, closedWorld);
noSuchMethodRegistry.emitDiagnostic();
int totalMethodCount = generatedCode.length;
if (totalMethodCount != preMirrorsMethodCount) {
@@ -1747,7 +1753,7 @@
if (!type.isRaw) return false;
ClassElement classElement = type.element;
if (isInterceptorClass(classElement)) return false;
- return compiler.closedWorld.hasOnlySubclasses(classElement);
+ return _closedWorld.hasOnlySubclasses(classElement);
}
WorldImpact registerUsedElement(Element element, {bool forResolution}) {
@@ -2357,7 +2363,24 @@
jsInteropAnalysis.onQueueClosed();
}
- WorldImpact onCodegenStart() {
+ // TODO(johnniwinther): Create a CodegenPhase object for the backend to hold
+ // data only available during code generation.
+ ClosedWorld _closedWorldCache;
+ ClosedWorld get _closedWorld {
+ assert(invariant(NO_LOCATION_SPANNABLE, _closedWorldCache != null,
+ message: "ClosedWorld has not be set yet."));
+ return _closedWorldCache;
+ }
+
+ void set _closedWorld(ClosedWorld value) {
+ _closedWorldCache = value;
+ }
+
+ WorldImpact onCodegenStart(ClosedWorld closedWorld) {
+ _closedWorld = closedWorld;
+ _namer = determineNamer(_closedWorld);
+ tracer = new Tracer(_closedWorld, namer, compiler.outputProvider);
+ emitter.createEmitter(_namer, _closedWorld);
lookupMapAnalysis.onCodegenStart();
if (hasIsolateSupport) {
return enableIsolateSupport(forResolution: false);
@@ -2365,6 +2388,11 @@
return const WorldImpact();
}
+ void onCodegenEnd() {
+ sourceInformationStrategy.onComplete();
+ tracer.close();
+ }
+
/// Process backend specific annotations.
void processAnnotations(
Element element, ClosedWorldRefiner closedWorldRefiner) {
@@ -3206,6 +3234,7 @@
helpers.jsMutableIndexableClass;
ClassElement get indexingBehaviorImplementation =>
helpers.jsIndexingBehaviorInterface;
+ ClassElement get interceptorImplementation => helpers.jsInterceptorClass;
bool isDefaultEqualityImplementation(Element element) {
assert(element.name == '==');
diff --git a/pkg/compiler/lib/src/js_backend/enqueuer.dart b/pkg/compiler/lib/src/js_backend/enqueuer.dart
index 4784df0..da79b0e 100644
--- a/pkg/compiler/lib/src/js_backend/enqueuer.dart
+++ b/pkg/compiler/lib/src/js_backend/enqueuer.dart
@@ -86,7 +86,8 @@
CodegenWorldBuilder get universe => _universe;
// TODO(johnniwinther): Remove these hacks:
- ClosedWorld get _world => _backend.compiler.closedWorld;
+ ClosedWorld get _world =>
+ _backend.compiler.resolverWorld.closedWorldForTesting;
DumpInfoTask get _dumpInfoTask => _backend.compiler.dumpInfoTask;
bool get queueIsEmpty => _queue.isEmpty;
diff --git a/pkg/compiler/lib/src/js_backend/field_naming_mixin.dart b/pkg/compiler/lib/src/js_backend/field_naming_mixin.dart
index b5e3c71..d7a3ca9 100644
--- a/pkg/compiler/lib/src/js_backend/field_naming_mixin.dart
+++ b/pkg/compiler/lib/src/js_backend/field_naming_mixin.dart
@@ -24,8 +24,7 @@
names = new _FieldNamingScope.forBox(element.box, fieldRegistry);
} else {
ClassElement cls = element.enclosingClass;
- names = new _FieldNamingScope.forClass(
- cls, compiler.closedWorld, fieldRegistry);
+ names = new _FieldNamingScope.forClass(cls, closedWorld, fieldRegistry);
}
if (names.containsField(element)) {
diff --git a/pkg/compiler/lib/src/js_backend/frequency_namer.dart b/pkg/compiler/lib/src/js_backend/frequency_namer.dart
index 9636e67..0d4157b 100644
--- a/pkg/compiler/lib/src/js_backend/frequency_namer.dart
+++ b/pkg/compiler/lib/src/js_backend/frequency_namer.dart
@@ -25,7 +25,8 @@
jsAst.Name get staticsPropertyName =>
_staticsPropertyName ??= getFreshName(instanceScope, 'static');
- FrequencyBasedNamer(Compiler compiler) : super(compiler) {
+ FrequencyBasedNamer(JavaScriptBackend backend, ClosedWorld closedWorld)
+ : super(backend, closedWorld) {
fieldRegistry = new _FieldNamingRegistry(this);
}
diff --git a/pkg/compiler/lib/src/js_backend/minify_namer.dart b/pkg/compiler/lib/src/js_backend/minify_namer.dart
index 3e689d4..10504c4 100644
--- a/pkg/compiler/lib/src/js_backend/minify_namer.dart
+++ b/pkg/compiler/lib/src/js_backend/minify_namer.dart
@@ -12,7 +12,8 @@
_MinifiedFieldNamer,
_MinifyConstructorBodyNamer,
_MinifiedOneShotInterceptorNamer {
- MinifyNamer(Compiler compiler) : super(compiler) {
+ MinifyNamer(JavaScriptBackend backend, ClosedWorld closedWorld)
+ : super(backend, closedWorld) {
reserveBackendNames();
fieldRegistry = new _FieldNamingRegistry(this);
}
diff --git a/pkg/compiler/lib/src/js_backend/mirrors_analysis.dart b/pkg/compiler/lib/src/js_backend/mirrors_analysis.dart
index 5207421..e7be92d 100644
--- a/pkg/compiler/lib/src/js_backend/mirrors_analysis.dart
+++ b/pkg/compiler/lib/src/js_backend/mirrors_analysis.dart
@@ -82,7 +82,7 @@
return includedEnclosing || _backend.requiredByMirrorSystem(element);
}
- /// Enqeue the constructor [ctor] if it is required for reflection.
+ /// Enqueue the constructor [ctor] if it is required for reflection.
///
/// [enclosingWasIncluded] provides a hint whether the enclosing element was
/// needed for reflection.
@@ -99,7 +99,7 @@
}
}
- /// Enqeue the member [element] if it is required for reflection.
+ /// Enqueue the member [element] if it is required for reflection.
///
/// [enclosingWasIncluded] provides a hint whether the enclosing element was
/// needed for reflection.
@@ -131,7 +131,7 @@
}
}
- /// Enqeue the member [element] if it is required for reflection.
+ /// Enqueue the member [element] if it is required for reflection.
///
/// [enclosingWasIncluded] provides a hint whether the enclosing element was
/// needed for reflection.
@@ -163,7 +163,7 @@
}
}
- /// Enqeue special classes that might not be visible by normal means or that
+ /// Enqueue special classes that might not be visible by normal means or that
/// would not normally be enqueued:
///
/// [Closure] is treated specially as it is the superclass of all closures.
@@ -182,7 +182,7 @@
}
}
- /// Enqeue all local members of the library [lib] if they are required for
+ /// Enqueue all local members of the library [lib] if they are required for
/// reflection.
void _enqueueReflectiveElementsInLibrary(
LibraryElement lib, Iterable<ClassEntity> recents) {
diff --git a/pkg/compiler/lib/src/js_backend/namer.dart b/pkg/compiler/lib/src/js_backend/namer.dart
index e0511a3..c03056a 100644
--- a/pkg/compiler/lib/src/js_backend/namer.dart
+++ b/pkg/compiler/lib/src/js_backend/namer.dart
@@ -402,7 +402,8 @@
static final RegExp IDENTIFIER = new RegExp(r'^[A-Za-z_$][A-Za-z0-9_$]*$');
static final RegExp NON_IDENTIFIER_CHAR = new RegExp(r'[^A-Za-z_0-9$]');
- final Compiler compiler;
+ final JavaScriptBackend backend;
+ final ClosedWorld closedWorld;
/// Used disambiguated names in the global namespace, issued by
/// [_disambiguateGlobal], and [_disambiguateInternalGlobal].
@@ -459,23 +460,22 @@
final Map<LibraryElement, String> _libraryKeys =
new HashMap<LibraryElement, String>();
- Namer(Compiler compiler)
- : compiler = compiler,
- constantHasher = new ConstantCanonicalHasher(compiler),
- functionTypeNamer = new FunctionTypeNamer(compiler) {
+ Namer(JavaScriptBackend backend, this.closedWorld)
+ : this.backend = backend,
+ constantHasher =
+ new ConstantCanonicalHasher(backend.rtiEncoder, backend.reporter),
+ functionTypeNamer = new FunctionTypeNamer(backend.rtiEncoder) {
_literalAsyncPrefix = new StringBackedName(asyncPrefix);
_literalGetterPrefix = new StringBackedName(getterPrefix);
_literalSetterPrefix = new StringBackedName(setterPrefix);
_literalLazyGetterPrefix = new StringBackedName(lazyGetterPrefix);
}
- JavaScriptBackend get backend => compiler.backend;
-
BackendHelpers get helpers => backend.helpers;
- DiagnosticReporter get reporter => compiler.reporter;
+ DiagnosticReporter get reporter => backend.reporter;
- CoreClasses get coreClasses => compiler.coreClasses;
+ CoreClasses get coreClasses => closedWorld.coreClasses;
String get deferredTypesName => 'deferredTypes';
String get isolateName => 'Isolate';
@@ -591,8 +591,9 @@
String constantLongName(ConstantValue constant) {
String longName = constantLongNames[constant];
if (longName == null) {
- longName =
- new ConstantNamingVisitor(compiler, constantHasher).getName(constant);
+ longName = new ConstantNamingVisitor(
+ backend.rtiEncoder, reporter, constantHasher)
+ .getName(constant);
constantLongNames[constant] = longName;
}
return longName;
@@ -854,7 +855,6 @@
// mangle the field names of classes extending native classes.
// Methods on such classes are stored on the interceptor, not the instance,
// so only fields have the potential to clash with a native property name.
- ClosedWorld closedWorld = compiler.closedWorld;
if (closedWorld.isUsedAsMixin(enclosingClass) ||
_isShadowingSuperField(element) ||
_isUserClassExtendingNative(enclosingClass)) {
@@ -1643,7 +1643,8 @@
static const MAX_EXTRA_LENGTH = 30;
static const DEFAULT_TAG_LENGTH = 3;
- final Compiler compiler;
+ final RuntimeTypesEncoder rtiEncoder;
+ final DiagnosticReporter reporter;
final ConstantCanonicalHasher hasher;
String root = null; // First word, usually a type name.
@@ -1651,9 +1652,7 @@
List<String> fragments = <String>[];
int length = 0;
- ConstantNamingVisitor(this.compiler, this.hasher);
-
- DiagnosticReporter get reporter => compiler.reporter;
+ ConstantNamingVisitor(this.rtiEncoder, this.reporter, this.hasher);
String getName(ConstantValue constant) {
_visit(constant);
@@ -1797,8 +1796,7 @@
String name = type.element?.name;
if (name == null) {
// e.g. DartType 'dynamic' has no element.
- JavaScriptBackend backend = compiler.backend;
- name = backend.rtiEncoder.getTypeRepresentationForTypeConstant(type);
+ name = rtiEncoder.getTypeRepresentationForTypeConstant(type);
}
addIdentifier(name);
add(getHashTag(constant, 3));
@@ -1846,12 +1844,11 @@
static const _MASK = 0x1fffffff;
static const _UINT32_LIMIT = 4 * 1024 * 1024 * 1024;
- final Compiler compiler;
+ final DiagnosticReporter reporter;
+ final RuntimeTypesEncoder rtiEncoder;
final Map<ConstantValue, int> hashes = new Map<ConstantValue, int>();
- ConstantCanonicalHasher(this.compiler);
-
- DiagnosticReporter get reporter => compiler.reporter;
+ ConstantCanonicalHasher(this.rtiEncoder, this.reporter);
int getHash(ConstantValue constant) => _visit(constant);
@@ -1918,9 +1915,8 @@
@override
int visitType(TypeConstantValue constant, [_]) {
DartType type = constant.representedType;
- JavaScriptBackend backend = compiler.backend;
// This name includes the library name and type parameters.
- String name = backend.rtiEncoder.getTypeRepresentationForTypeConstant(type);
+ String name = rtiEncoder.getTypeRepresentationForTypeConstant(type);
return _hashString(4, name);
}
@@ -2027,12 +2023,10 @@
}
class FunctionTypeNamer extends BaseDartTypeVisitor {
- final Compiler compiler;
+ final RuntimeTypesEncoder rtiEncoder;
StringBuffer sb;
- FunctionTypeNamer(this.compiler);
-
- JavaScriptBackend get backend => compiler.backend;
+ FunctionTypeNamer(this.rtiEncoder);
String computeName(DartType type) {
sb = new StringBuffer();
@@ -2049,7 +2043,7 @@
}
visitFunctionType(FunctionType type, _) {
- if (backend.rtiEncoder.isSimpleFunctionType(type)) {
+ if (rtiEncoder.isSimpleFunctionType(type)) {
sb.write('args${type.parameterTypes.length}');
return;
}
diff --git a/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart b/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart
index 96d991a..d4e36a0 100644
--- a/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart
@@ -6,10 +6,14 @@
class ClassStubGenerator {
final Namer namer;
- final Compiler compiler;
final JavaScriptBackend backend;
+ final CodegenWorldBuilder codegenWorld;
+ final ClosedWorld closedWorld;
+ final bool enableMinification;
- ClassStubGenerator(this.compiler, this.namer, this.backend);
+ ClassStubGenerator(
+ this.namer, this.backend, this.codegenWorld, this.closedWorld,
+ {this.enableMinification});
jsAst.Expression generateClassConstructor(ClassElement classElement,
Iterable<jsAst.Name> fields, bool hasRtiField) {
@@ -93,7 +97,7 @@
for (Selector selector in selectors.keys) {
if (generatedSelectors.contains(selector)) continue;
if (!selector.appliesUnnamed(member)) continue;
- if (selectors[selector].applies(member, selector, compiler.closedWorld)) {
+ if (selectors[selector].applies(member, selector, closedWorld)) {
generatedSelectors.add(selector);
jsAst.Name invocationName = namer.invocationName(selector);
@@ -126,7 +130,7 @@
Map<jsAst.Name, Selector> jsNames = <jsAst.Name, Selector>{};
// Do not generate no such method handlers if there is no class.
- if (compiler.codegenWorld.directlyInstantiatedClasses.isEmpty) {
+ if (codegenWorld.directlyInstantiatedClasses.isEmpty) {
return jsNames;
}
@@ -134,16 +138,16 @@
String ignore, Map<Selector, SelectorConstraints> selectors) {
for (Selector selector in selectors.keys) {
SelectorConstraints maskSet = selectors[selector];
- if (maskSet.needsNoSuchMethodHandling(selector, compiler.closedWorld)) {
+ if (maskSet.needsNoSuchMethodHandling(selector, closedWorld)) {
jsAst.Name jsName = namer.invocationMirrorInternalName(selector);
jsNames[jsName] = selector;
}
}
}
- compiler.codegenWorld.forEachInvokedName(addNoSuchMethodHandlers);
- compiler.codegenWorld.forEachInvokedGetter(addNoSuchMethodHandlers);
- compiler.codegenWorld.forEachInvokedSetter(addNoSuchMethodHandlers);
+ codegenWorld.forEachInvokedName(addNoSuchMethodHandlers);
+ codegenWorld.forEachInvokedGetter(addNoSuchMethodHandlers);
+ codegenWorld.forEachInvokedSetter(addNoSuchMethodHandlers);
return jsNames;
}
@@ -175,8 +179,8 @@
'noSuchMethodName': namer.noSuchMethodName,
'createInvocationMirror': backend.emitter
.staticFunctionAccess(backend.helpers.createInvocationMirror),
- 'methodName': js.quoteName(
- compiler.options.enableMinification ? internalName : methodName),
+ 'methodName':
+ js.quoteName(enableMinification ? internalName : methodName),
'internalName': js.quoteName(internalName),
'type': js.number(type),
'arguments':
diff --git a/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart b/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart
index eabb905..9c39229 100644
--- a/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart
+++ b/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart
@@ -13,12 +13,11 @@
* The code for the containing (used) methods must exist in the `universe`.
*/
class CodeEmitterTask extends CompilerTask {
- // TODO(floitsch): the code-emitter task should not need a namer.
- final Namer namer;
- final TypeTestRegistry typeTestRegistry;
+ TypeTestRegistry typeTestRegistry;
NativeEmitter nativeEmitter;
MetadataCollector metadataCollector;
- Emitter emitter;
+ EmitterFactory _emitterFactory;
+ Emitter _emitter;
final Compiler compiler;
/// Records if a type variable is read dynamically for type tests.
@@ -34,30 +33,36 @@
/// Contains a list of all classes that are emitted.
Set<ClassElement> neededClasses;
- CodeEmitterTask(Compiler compiler, Namer namer, bool generateSourceMap,
- bool useStartupEmitter)
+ CodeEmitterTask(
+ Compiler compiler, bool generateSourceMap, bool useStartupEmitter)
: compiler = compiler,
- this.namer = namer,
- this.typeTestRegistry = new TypeTestRegistry(compiler),
super(compiler.measurer) {
nativeEmitter = new NativeEmitter(this);
if (USE_LAZY_EMITTER) {
- emitter = new lazy_js_emitter.Emitter(compiler, namer, nativeEmitter);
+ _emitterFactory = new lazy_js_emitter.EmitterFactory();
} else if (useStartupEmitter) {
- emitter = new startup_js_emitter.Emitter(
- compiler, namer, nativeEmitter, generateSourceMap);
+ _emitterFactory = new startup_js_emitter.EmitterFactory(
+ generateSourceMap: generateSourceMap);
} else {
- emitter =
- new full_js_emitter.Emitter(compiler, namer, generateSourceMap, this);
+ _emitterFactory = new full_js_emitter.EmitterFactory(
+ generateSourceMap: generateSourceMap);
}
- metadataCollector = new MetadataCollector(compiler, emitter);
+ }
+
+ Emitter get emitter {
+ assert(invariant(NO_LOCATION_SPANNABLE, _emitter != null,
+ message: "Emitter has not been created yet."));
+ return _emitter;
}
String get name => 'Code emitter';
/// Returns the string that is used to find library patches that are
/// specialized for the emitter.
- String get patchVersion => emitter.patchVersion;
+ String get patchVersion => _emitterFactory.patchVersion;
+
+ /// Returns true, if the emitter supports reflection.
+ bool get supportsReflection => _emitterFactory.supportsReflection;
/// Returns the closure expression of a static function.
jsAst.Expression isolateStaticClosureAccess(MethodElement element) {
@@ -138,13 +143,22 @@
return typeTestRegistry.computeRtiNeededClasses();
}
- int assembleProgram() {
+ /// Creates the [Emitter] for this task.
+ void createEmitter(Namer namer, ClosedWorld closedWorld) {
+ measure(() {
+ _emitter = _emitterFactory.createEmitter(this, namer, closedWorld);
+ metadataCollector = new MetadataCollector(compiler, _emitter);
+ typeTestRegistry = new TypeTestRegistry(compiler, closedWorld);
+ });
+ }
+
+ int assembleProgram(Namer namer, ClosedWorld closedWorld) {
return measure(() {
emitter.invalidateCaches();
Set<ClassElement> rtiNeededClasses = _finalizeRti();
- ProgramBuilder programBuilder =
- new ProgramBuilder(compiler, namer, this, emitter, rtiNeededClasses);
+ ProgramBuilder programBuilder = new ProgramBuilder(
+ compiler, namer, this, emitter, closedWorld, rtiNeededClasses);
int size = emitter.emitProgram(programBuilder);
// TODO(floitsch): we shouldn't need the `neededClasses` anymore.
neededClasses = programBuilder.collector.neededClasses;
@@ -153,18 +167,24 @@
}
}
-abstract class Emitter {
+abstract class EmitterFactory {
/// Returns the string that is used to find library patches that are
/// specialized for this emitter.
String get patchVersion;
+ /// Returns true, if the emitter supports reflection.
+ bool get supportsReflection;
+
+ /// Create the [Emitter] for the emitter [task] that uses the given [namer].
+ Emitter createEmitter(
+ CodeEmitterTask task, Namer namer, ClosedWorld closedWorld);
+}
+
+abstract class Emitter {
/// Uses the [programBuilder] to generate a model of the program, emits
/// the program, and returns the size of the generated output.
int emitProgram(ProgramBuilder programBuilder);
- /// Returns true, if the emitter supports reflection.
- bool get supportsReflection;
-
/// Returns the JS function that must be invoked to get the value of the
/// lazily initialized static.
jsAst.Expression isolateLazyInitializerAccess(FieldElement element);
diff --git a/pkg/compiler/lib/src/js_emitter/full_emitter/class_emitter.dart b/pkg/compiler/lib/src/js_emitter/full_emitter/class_emitter.dart
index 5a6fb44..3f813ad 100644
--- a/pkg/compiler/lib/src/js_emitter/full_emitter/class_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/full_emitter/class_emitter.dart
@@ -5,8 +5,13 @@
part of dart2js.js_emitter.full_emitter;
class ClassEmitter extends CodeEmitterHelper {
+ final ClosedWorld closedWorld;
+
+ ClassEmitter(this.closedWorld);
+
ClassStubGenerator get _stubGenerator =>
- new ClassStubGenerator(compiler, namer, backend);
+ new ClassStubGenerator(namer, backend, codegenWorld, closedWorld,
+ enableMinification: compiler.options.enableMinification);
/**
* Documentation wanted -- johnniwinther
diff --git a/pkg/compiler/lib/src/js_emitter/full_emitter/code_emitter_helper.dart b/pkg/compiler/lib/src/js_emitter/full_emitter/code_emitter_helper.dart
index 6c7ee56..c1acde7 100644
--- a/pkg/compiler/lib/src/js_emitter/full_emitter/code_emitter_helper.dart
+++ b/pkg/compiler/lib/src/js_emitter/full_emitter/code_emitter_helper.dart
@@ -19,6 +19,8 @@
DiagnosticReporter get reporter => compiler.reporter;
+ CodegenWorldBuilder get codegenWorld => compiler.codegenWorld;
+
String get n => emitter.n;
String get _ => emitter._;
diff --git a/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart b/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
index af5e764..1affdaf 100644
--- a/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
@@ -52,13 +52,15 @@
TypeVariableHandler;
import '../../universe/call_structure.dart' show CallStructure;
import '../../universe/selector.dart' show Selector;
+import '../../universe/world_builder.dart' show CodegenWorldBuilder;
import '../../util/characters.dart' show $$, $A, $HASH, $Z, $a, $z;
import '../../util/uri_extras.dart' show relativize;
import '../../util/util.dart' show equalElements;
+import '../../world.dart' show ClosedWorld;
import '../constant_ordering.dart' show deepCompareConstants;
import '../headers.dart';
-import '../js_emitter.dart' hide Emitter;
-import '../js_emitter.dart' as js_emitter show Emitter;
+import '../js_emitter.dart' hide Emitter, EmitterFactory;
+import '../js_emitter.dart' as js_emitter show Emitter, EmitterFactory;
import '../model.dart';
import '../program_builder/program_builder.dart';
@@ -72,6 +74,25 @@
part 'nsm_emitter.dart';
part 'setup_program_builder.dart';
+class EmitterFactory implements js_emitter.EmitterFactory {
+ final bool generateSourceMap;
+
+ EmitterFactory({this.generateSourceMap});
+
+ @override
+ String get patchVersion => "full";
+
+ @override
+ bool get supportsReflection => true;
+
+ @override
+ Emitter createEmitter(
+ CodeEmitterTask task, Namer namer, ClosedWorld closedWorld) {
+ return new Emitter(
+ task.compiler, namer, closedWorld, generateSourceMap, task);
+ }
+}
+
class Emitter implements js_emitter.Emitter {
final Compiler compiler;
final CodeEmitterTask task;
@@ -83,9 +104,9 @@
List<TypedefElement> typedefsNeededForReflection;
final ContainerBuilder containerBuilder = new ContainerBuilder();
- final ClassEmitter classEmitter = new ClassEmitter();
- final NsmEmitter nsmEmitter = new NsmEmitter();
- final InterceptorEmitter interceptorEmitter = new InterceptorEmitter();
+ final ClassEmitter classEmitter;
+ final NsmEmitter nsmEmitter;
+ final InterceptorEmitter interceptorEmitter;
// TODO(johnniwinther): Wrap these fields in a caching strategy.
final Set<ConstantValue> cachedEmittedConstants;
@@ -154,18 +175,30 @@
final bool generateSourceMap;
- Emitter(Compiler compiler, Namer namer, this.generateSourceMap, this.task)
+ Emitter(Compiler compiler, Namer namer, ClosedWorld closedWorld,
+ this.generateSourceMap, this.task)
: this.compiler = compiler,
this.namer = namer,
cachedEmittedConstants = compiler.cacheStrategy.newSet(),
cachedClassBuilders = compiler.cacheStrategy.newMap(),
- cachedElements = compiler.cacheStrategy.newSet() {
+ cachedElements = compiler.cacheStrategy.newSet(),
+ classEmitter = new ClassEmitter(closedWorld),
+ interceptorEmitter = new InterceptorEmitter(closedWorld),
+ nsmEmitter = new NsmEmitter(closedWorld) {
constantEmitter = new ConstantEmitter(
compiler, namer, this.constantReference, constantListGenerator);
containerBuilder.emitter = this;
classEmitter.emitter = this;
nsmEmitter.emitter = this;
interceptorEmitter.emitter = this;
+ if (compiler.options.hasIncrementalSupport) {
+ // Much like a scout, an incremental compiler is always prepared. For
+ // mixins, classes, and lazy statics, at least.
+ needsClassSupport = true;
+ needsMixinSupport = true;
+ needsLazyInitializer = true;
+ needsStructuredMemberInfo = true;
+ }
}
DiagnosticReporter get reporter => compiler.reporter;
@@ -189,9 +222,6 @@
}
@override
- String get patchVersion => "full";
-
- @override
bool isConstantInlinedOrAlreadyEmitted(ConstantValue constant) {
if (constant.isFunction) return true; // Already emitted.
if (constant.isPrimitive) return true; // Inlined.
@@ -273,9 +303,6 @@
String get globalsHolder => r"$globals$";
@override
- bool get supportsReflection => true;
-
- @override
jsAst.Expression generateEmbeddedGlobalAccess(String global) {
return js(generateEmbeddedGlobalAccessString(global));
}
diff --git a/pkg/compiler/lib/src/js_emitter/full_emitter/interceptor_emitter.dart b/pkg/compiler/lib/src/js_emitter/full_emitter/interceptor_emitter.dart
index 0da9ca3..1c90f92 100644
--- a/pkg/compiler/lib/src/js_emitter/full_emitter/interceptor_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/full_emitter/interceptor_emitter.dart
@@ -5,8 +5,11 @@
part of dart2js.js_emitter.full_emitter;
class InterceptorEmitter extends CodeEmitterHelper {
+ final ClosedWorld closedWorld;
final Set<jsAst.Name> interceptorInvocationNames = new Set<jsAst.Name>();
+ InterceptorEmitter(this.closedWorld);
+
void recordMangledNameOfMemberMethod(
FunctionElement member, jsAst.Name name) {
if (backend.isInterceptedMethod(member)) {
@@ -17,7 +20,7 @@
jsAst.Expression buildGetInterceptorMethod(
jsAst.Name key, Set<ClassElement> classes) {
InterceptorStubGenerator stubGenerator =
- new InterceptorStubGenerator(compiler, namer, backend);
+ new InterceptorStubGenerator(compiler, namer, backend, closedWorld);
jsAst.Expression function =
stubGenerator.generateGetInterceptorMethod(classes);
@@ -53,7 +56,7 @@
..sort();
InterceptorStubGenerator stubGenerator =
- new InterceptorStubGenerator(compiler, namer, backend);
+ new InterceptorStubGenerator(compiler, namer, backend, closedWorld);
String globalObject =
namer.globalObjectFor(backend.helpers.interceptorsLibrary);
for (jsAst.Name name in names) {
diff --git a/pkg/compiler/lib/src/js_emitter/full_emitter/nsm_emitter.dart b/pkg/compiler/lib/src/js_emitter/full_emitter/nsm_emitter.dart
index f0a6e0f..9bdf146 100644
--- a/pkg/compiler/lib/src/js_emitter/full_emitter/nsm_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/full_emitter/nsm_emitter.dart
@@ -5,8 +5,11 @@
part of dart2js.js_emitter.full_emitter;
class NsmEmitter extends CodeEmitterHelper {
+ final ClosedWorld closedWorld;
final List<Selector> trivialNsmHandlers = <Selector>[];
+ NsmEmitter(this.closedWorld);
+
/// If this is true then we can generate the noSuchMethod handlers at startup
/// time, instead of them being emitted as part of the Object class.
bool get generateTrivialNsmHandlers => true;
@@ -19,8 +22,9 @@
static const MAX_MINIFIED_LENGTH_FOR_DIFF_ENCODING = 4;
void emitNoSuchMethodHandlers(AddPropertyFunction addProperty) {
- ClassStubGenerator generator =
- new ClassStubGenerator(compiler, namer, backend);
+ ClassStubGenerator generator = new ClassStubGenerator(
+ namer, backend, codegenWorld, closedWorld,
+ enableMinification: compiler.options.enableMinification);
// Keep track of the JavaScript names we've already added so we
// do not introduce duplicates (bad for code size).
@@ -55,7 +59,7 @@
generator.generateStubForNoSuchMethod(jsName, selector);
addProperty(method.name, method.code);
if (reflectionName != null) {
- bool accessible = compiler.closedWorld.allFunctions
+ bool accessible = closedWorld.allFunctions
.filter(selector, null)
.any((Element e) => backend.isAccessibleByReflection(e));
addProperty(
diff --git a/pkg/compiler/lib/src/js_emitter/interceptor_stub_generator.dart b/pkg/compiler/lib/src/js_emitter/interceptor_stub_generator.dart
index 265c946..9a7d2cc 100644
--- a/pkg/compiler/lib/src/js_emitter/interceptor_stub_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/interceptor_stub_generator.dart
@@ -8,8 +8,10 @@
final Compiler compiler;
final Namer namer;
final JavaScriptBackend backend;
+ final ClosedWorld closedWorld;
- InterceptorStubGenerator(this.compiler, this.namer, this.backend);
+ InterceptorStubGenerator(
+ this.compiler, this.namer, this.backend, this.closedWorld);
Emitter get emitter => backend.emitter.emitter;
@@ -248,8 +250,8 @@
bool containsJsIndexable =
helpers.jsIndexingBehaviorInterface.isResolved &&
classes.any((cls) {
- return compiler.closedWorld
- .isSubtypeOf(cls, helpers.jsIndexingBehaviorInterface);
+ return closedWorld.isSubtypeOf(
+ cls, helpers.jsIndexingBehaviorInterface);
});
// The index set operator requires a check on its set value in
// checked mode, so we don't optimize the interceptor if the
diff --git a/pkg/compiler/lib/src/js_emitter/js_emitter.dart b/pkg/compiler/lib/src/js_emitter/js_emitter.dart
index e902ab5..5d715a3 100644
--- a/pkg/compiler/lib/src/js_emitter/js_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/js_emitter.dart
@@ -56,8 +56,10 @@
TypeVariableHandler;
import '../universe/call_structure.dart' show CallStructure;
import '../universe/selector.dart' show Selector;
-import '../universe/world_builder.dart' show SelectorConstraints;
+import '../universe/world_builder.dart'
+ show CodegenWorldBuilder, SelectorConstraints;
import '../util/util.dart' show Setlet;
+import '../world.dart' show ClosedWorld;
import 'full_emitter/emitter.dart' as full_js_emitter;
import 'lazy_emitter/emitter.dart' as lazy_js_emitter;
import 'model.dart';
diff --git a/pkg/compiler/lib/src/js_emitter/lazy_emitter/emitter.dart b/pkg/compiler/lib/src/js_emitter/lazy_emitter/emitter.dart
index 64e1f79b..3714a08 100644
--- a/pkg/compiler/lib/src/js_emitter/lazy_emitter/emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/lazy_emitter/emitter.dart
@@ -13,12 +13,27 @@
show ClassElement, Element, FieldElement, FunctionElement;
import '../../js/js.dart' as js;
import '../../js_backend/js_backend.dart' show JavaScriptBackend, Namer;
-import '../js_emitter.dart' show NativeEmitter;
-import '../js_emitter.dart' as emitterTask show Emitter;
+import '../../world.dart' show ClosedWorld;
+import '../js_emitter.dart' show CodeEmitterTask, NativeEmitter;
+import '../js_emitter.dart' as emitterTask show Emitter, EmitterFactory;
import '../model.dart';
import '../program_builder/program_builder.dart' show ProgramBuilder;
import 'model_emitter.dart';
+class EmitterFactory implements emitterTask.EmitterFactory {
+ @override
+ String get patchVersion => "lazy";
+
+ @override
+ bool get supportsReflection => false;
+
+ @override
+ Emitter createEmitter(
+ CodeEmitterTask task, Namer namer, ClosedWorld closedWorld) {
+ return new Emitter(task.compiler, namer, task.nativeEmitter);
+ }
+}
+
class Emitter implements emitterTask.Emitter {
final Compiler _compiler;
final Namer namer;
@@ -34,17 +49,11 @@
DiagnosticReporter get reporter => _compiler.reporter;
@override
- String get patchVersion => "lazy";
-
- @override
int emitProgram(ProgramBuilder programBuilder) {
Program program = programBuilder.buildProgram();
return _emitter.emitProgram(program);
}
- @override
- bool get supportsReflection => false;
-
// TODO(floitsch): copied from full emitter. Adjust or share.
@override
bool isConstantInlinedOrAlreadyEmitted(ConstantValue constant) {
diff --git a/pkg/compiler/lib/src/js_emitter/parameter_stub_generator.dart b/pkg/compiler/lib/src/js_emitter/parameter_stub_generator.dart
index c63527d..ad7f2ed 100644
--- a/pkg/compiler/lib/src/js_emitter/parameter_stub_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/parameter_stub_generator.dart
@@ -10,8 +10,10 @@
final Namer namer;
final Compiler compiler;
final JavaScriptBackend backend;
+ final ClosedWorld closedWorld;
- ParameterStubGenerator(this.compiler, this.namer, this.backend);
+ ParameterStubGenerator(
+ this.compiler, this.namer, this.backend, this.closedWorld);
Emitter get emitter => backend.emitter.emitter;
CodeEmitterTask get emitterTask => backend.emitter;
@@ -267,8 +269,7 @@
for (Selector selector in selectors.keys) {
if (renamedCallSelectors.contains(selector)) continue;
if (!selector.appliesUnnamed(member)) continue;
- if (!selectors[selector]
- .applies(member, selector, compiler.closedWorld)) {
+ if (!selectors[selector].applies(member, selector, closedWorld)) {
continue;
}
diff --git a/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart b/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart
index 6e43f98..5389c2c 100644
--- a/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart
+++ b/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart
@@ -14,6 +14,7 @@
// TODO(floitsch): the code-emitter task should not need a namer.
final Namer namer;
final Compiler compiler;
+ final ClosedWorld closedWorld;
final Set<ClassElement> rtiNeededClasses;
final Emitter emitter;
@@ -46,7 +47,8 @@
CoreClasses get coreClasses => compiler.coreClasses;
- Collector(this.compiler, this.namer, this.rtiNeededClasses, this.emitter);
+ Collector(this.compiler, this.namer, this.closedWorld, this.rtiNeededClasses,
+ this.emitter);
Set<ClassElement> computeInterceptorsReferencedFromConstants() {
Set<ClassElement> classes = new Set<ClassElement>();
@@ -129,7 +131,7 @@
final onlyForRti = classesOnlyNeededForRti.contains(cls);
if (!onlyForRti) {
backend.retainMetadataOf(cls);
- new FieldVisitor(compiler, namer).visitFields(cls, false,
+ new FieldVisitor(compiler, namer, closedWorld).visitFields(cls, false,
(Element member, js.Name name, js.Name accessorName,
bool needsGetter, bool needsSetter, bool needsCheckedSetter) {
bool needsAccessor = needsGetter || needsSetter;
@@ -169,8 +171,8 @@
/// Compute all the classes and typedefs that must be emitted.
void computeNeededDeclarations() {
// Compute needed typedefs.
- typedefsNeededForReflection = Elements.sortedByPosition(compiler
- .closedWorld.allTypedefs
+ typedefsNeededForReflection = Elements.sortedByPosition(closedWorld
+ .allTypedefs
.where(backend.isAccessibleByReflection)
.toList());
diff --git a/pkg/compiler/lib/src/js_emitter/program_builder/field_visitor.dart b/pkg/compiler/lib/src/js_emitter/program_builder/field_visitor.dart
index 1f6956d..75ca6f5 100644
--- a/pkg/compiler/lib/src/js_emitter/program_builder/field_visitor.dart
+++ b/pkg/compiler/lib/src/js_emitter/program_builder/field_visitor.dart
@@ -33,10 +33,11 @@
class FieldVisitor {
final Compiler compiler;
final Namer namer;
+ final ClosedWorld closedWorld;
JavaScriptBackend get backend => compiler.backend;
- FieldVisitor(this.compiler, this.namer);
+ FieldVisitor(this.compiler, this.namer, this.closedWorld);
/**
* Invokes [f] for each of the fields of [element].
@@ -140,7 +141,7 @@
if (fieldAccessNeverThrows(field)) return false;
if (backend.shouldRetainGetter(field)) return true;
return field.isClassMember &&
- compiler.codegenWorld.hasInvokedGetter(field, compiler.closedWorld);
+ compiler.codegenWorld.hasInvokedGetter(field, closedWorld);
}
bool fieldNeedsSetter(VariableElement field) {
@@ -149,7 +150,7 @@
if (field.isFinal || field.isConst) return false;
if (backend.shouldRetainSetter(field)) return true;
return field.isClassMember &&
- compiler.codegenWorld.hasInvokedSetter(field, compiler.closedWorld);
+ compiler.codegenWorld.hasInvokedSetter(field, closedWorld);
}
static bool fieldAccessNeverThrows(VariableElement field) {
diff --git a/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart b/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
index 1ee47ed..fd18152 100644
--- a/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
+++ b/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
@@ -34,6 +34,7 @@
import '../../universe/selector.dart' show Selector;
import '../../universe/world_builder.dart'
show CodegenWorldBuilder, SelectorConstraints;
+import '../../world.dart' show ClosedWorld;
import '../js_emitter.dart'
show
ClassStubGenerator,
@@ -57,6 +58,7 @@
final Compiler _compiler;
final Namer namer;
final CodeEmitterTask _task;
+ final ClosedWorld closedWorld;
/// Contains the collected information the program builder used to build
/// the model.
@@ -71,11 +73,12 @@
bool _storeFunctionTypesInMetadata = false;
ProgramBuilder(Compiler compiler, Namer namer, this._task, Emitter emitter,
- Set<ClassElement> rtiNeededClasses)
+ ClosedWorld closedWorld, Set<ClassElement> rtiNeededClasses)
: this._compiler = compiler,
this.namer = namer,
- this.collector =
- new Collector(compiler, namer, rtiNeededClasses, emitter),
+ this.closedWorld = closedWorld,
+ this.collector = new Collector(
+ compiler, namer, closedWorld, rtiNeededClasses, emitter),
this._registry = new Registry(compiler);
JavaScriptBackend get backend => _compiler.backend;
@@ -205,7 +208,7 @@
js.Expression _buildTypeToInterceptorMap() {
InterceptorStubGenerator stubGenerator =
- new InterceptorStubGenerator(_compiler, namer, backend);
+ new InterceptorStubGenerator(_compiler, namer, backend, closedWorld);
return stubGenerator.generateTypeToInterceptorMap();
}
@@ -517,8 +520,9 @@
List<Method> methods = [];
List<StubMethod> callStubs = <StubMethod>[];
- ClassStubGenerator classStubGenerator =
- new ClassStubGenerator(_compiler, namer, backend);
+ ClassStubGenerator classStubGenerator = new ClassStubGenerator(
+ namer, backend, universe, closedWorld,
+ enableMinification: _compiler.options.enableMinification);
RuntimeTypeGenerator runtimeTypeGenerator =
new RuntimeTypeGenerator(_compiler, _task, namer);
@@ -676,7 +680,7 @@
bool _methodCanBeApplied(FunctionElement method) {
return backend.hasFunctionApplySupport &&
- _compiler.closedWorld.getMightBePassedToApply(method);
+ closedWorld.getMightBePassedToApply(method);
}
// TODO(herhut): Refactor incremental compilation and remove method.
@@ -736,9 +740,8 @@
isClosureCallMethod = true;
} else {
// Careful with operators.
- canTearOff =
- universe.hasInvokedGetter(element, _compiler.closedWorld) ||
- (canBeReflected && !element.isOperator);
+ canTearOff = universe.hasInvokedGetter(element, closedWorld) ||
+ (canBeReflected && !element.isOperator);
assert(canTearOff ||
!universe.methodsNeedingSuperGetter.contains(element));
tearOffName = namer.getterForElement(element);
@@ -813,7 +816,7 @@
if (!_methodNeedsStubs(element)) return const <ParameterStubMethod>[];
ParameterStubGenerator generator =
- new ParameterStubGenerator(_compiler, namer, backend);
+ new ParameterStubGenerator(_compiler, namer, backend, closedWorld);
return generator.generateParameterStubs(element, canTearOff: canTearOff);
}
@@ -841,7 +844,7 @@
Iterable<StaticStubMethod> _generateGetInterceptorMethods() {
InterceptorStubGenerator stubGenerator =
- new InterceptorStubGenerator(_compiler, namer, backend);
+ new InterceptorStubGenerator(_compiler, namer, backend, closedWorld);
String holderName = namer.globalObjectFor(helpers.interceptorsLibrary);
// TODO(floitsch): we shouldn't update the registry in the middle of
@@ -860,9 +863,13 @@
List<Field> _buildFields(Element holder, bool visitStatics) {
List<Field> fields = <Field>[];
- new FieldVisitor(_compiler, namer).visitFields(holder, visitStatics,
- (VariableElement field, js.Name name, js.Name accessorName,
- bool needsGetter, bool needsSetter, bool needsCheckedSetter) {
+ new FieldVisitor(_compiler, namer, closedWorld)
+ .visitFields(holder, visitStatics, (VariableElement field,
+ js.Name name,
+ js.Name accessorName,
+ bool needsGetter,
+ bool needsSetter,
+ bool needsCheckedSetter) {
assert(invariant(field, field.isDeclaration));
int getterFlags = 0;
@@ -901,7 +908,7 @@
Iterable<StaticStubMethod> _generateOneShotInterceptors() {
InterceptorStubGenerator stubGenerator =
- new InterceptorStubGenerator(_compiler, namer, backend);
+ new InterceptorStubGenerator(_compiler, namer, backend, closedWorld);
String holderName = namer.globalObjectFor(helpers.interceptorsLibrary);
// TODO(floitsch): we shouldn't update the registry in the middle of
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/emitter.dart
index 07be9d6..bac4f1e 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/emitter.dart
@@ -14,12 +14,32 @@
show ClassElement, Element, FieldElement, FunctionElement;
import '../../js/js.dart' as js;
import '../../js_backend/js_backend.dart' show JavaScriptBackend, Namer;
-import '../js_emitter.dart' show NativeEmitter;
-import '../js_emitter.dart' as emitterTask show Emitter;
+import '../../world.dart' show ClosedWorld;
+import '../js_emitter.dart' show CodeEmitterTask, NativeEmitter;
+import '../js_emitter.dart' as emitterTask show Emitter, EmitterFactory;
import '../model.dart';
import '../program_builder/program_builder.dart' show ProgramBuilder;
import 'model_emitter.dart';
+class EmitterFactory implements emitterTask.EmitterFactory {
+ final bool generateSourceMap;
+
+ EmitterFactory({this.generateSourceMap});
+
+ @override
+ String get patchVersion => "startup";
+
+ @override
+ bool get supportsReflection => false;
+
+ @override
+ Emitter createEmitter(
+ CodeEmitterTask task, Namer namer, ClosedWorld closedWorld) {
+ return new Emitter(
+ task.compiler, namer, task.nativeEmitter, generateSourceMap);
+ }
+}
+
class Emitter implements emitterTask.Emitter {
final Compiler _compiler;
final Namer namer;
@@ -37,18 +57,12 @@
DiagnosticReporter get reporter => _compiler.reporter;
@override
- String get patchVersion => "startup";
-
- @override
int emitProgram(ProgramBuilder programBuilder) {
Program program = programBuilder.buildProgram();
return _emitter.emitProgram(program);
}
@override
- bool get supportsReflection => false;
-
- @override
bool isConstantInlinedOrAlreadyEmitted(ConstantValue constant) {
return _emitter.isConstantInlinedOrAlreadyEmitted(constant);
}
diff --git a/pkg/compiler/lib/src/js_emitter/type_test_registry.dart b/pkg/compiler/lib/src/js_emitter/type_test_registry.dart
index c1ff342..040a4eb 100644
--- a/pkg/compiler/lib/src/js_emitter/type_test_registry.dart
+++ b/pkg/compiler/lib/src/js_emitter/type_test_registry.dart
@@ -37,8 +37,9 @@
}
final Compiler compiler;
+ final ClosedWorld closedWorld;
- TypeTestRegistry(this.compiler);
+ TypeTestRegistry(this.compiler, this.closedWorld);
JavaScriptBackend get backend => compiler.backend;
@@ -105,8 +106,7 @@
return false;
} else if (function.isInstanceMember) {
if (!function.enclosingClass.isClosure) {
- return compiler.codegenWorld
- .hasInvokedGetter(function, compiler.closedWorld);
+ return compiler.codegenWorld.hasInvokedGetter(function, closedWorld);
}
}
return false;
diff --git a/pkg/compiler/lib/src/kernel/kernel.dart b/pkg/compiler/lib/src/kernel/kernel.dart
index 77c7e2b..155f2a0 100644
--- a/pkg/compiler/lib/src/kernel/kernel.dart
+++ b/pkg/compiler/lib/src/kernel/kernel.dart
@@ -302,13 +302,8 @@
}
}
- // TODO(ahe): Remove this method when dart2js support generic type arguments.
- List<ir.TypeParameter> typeParametersNotImplemented() {
- return const <ir.TypeParameter>[];
- }
-
ir.FunctionType functionTypeToIr(FunctionType type) {
- List<ir.TypeParameter> typeParameters = typeParametersNotImplemented();
+ List<ir.TypeParameter> typeParameters = <ir.TypeParameter>[];
int requiredParameterCount = type.parameterTypes.length;
List<ir.DartType> positionalParameters =
new List<ir.DartType>.from(typesToIr(type.parameterTypes))
@@ -462,6 +457,8 @@
procedure.kind = irFunction.kind;
}
endFactoryScope(function);
+ irFunction.node.typeParameters
+ .addAll(typeVariablesToIr(function.typeVariables));
member.transformerFlags = visitor.transformerFlags;
assert(() {
visitor.locals.forEach(checkMember);
@@ -556,11 +553,14 @@
return typeParameters.putIfAbsent(variable, () {
ir.TypeParameter parameter = new ir.TypeParameter(variable.name, null);
addWork(variable, () {
- // TODO(ahe): This assignment will probably not be correct when dart2js
- // supports generic methods.
- ClassElement cls = variable.typeDeclaration;
- cls.ensureResolved(compiler.resolution);
- parameter.parent = classToIr(cls);
+ if (variable.typeDeclaration.isClass) {
+ ClassElement cls = variable.typeDeclaration;
+ cls.ensureResolved(compiler.resolution);
+ parameter.parent = classToIr(cls);
+ } else {
+ FunctionElement method = variable.typeDeclaration;
+ parameter.parent = functionToIr(method).function;
+ }
parameter.bound = typeToIr(variable.bound);
});
return parameter;
diff --git a/pkg/compiler/lib/src/kernel/kernel_visitor.dart b/pkg/compiler/lib/src/kernel/kernel_visitor.dart
index 2c3fcda..ea28f68 100644
--- a/pkg/compiler/lib/src/kernel/kernel_visitor.dart
+++ b/pkg/compiler/lib/src/kernel/kernel_visitor.dart
@@ -404,6 +404,7 @@
ir.Statement statement, Node node, JumpTarget jumpTarget) {
assert(node.isValidBreakTarget());
assert(jumpTarget == elements.getTargetDefinition(node));
+ associateNode(statement, node);
if (jumpTarget != null && jumpTarget.isBreakTarget) {
ir.LabeledStatement breakTarget = getBreakTarget(jumpTarget);
breakTarget.body = statement;
@@ -2025,8 +2026,7 @@
}
ir.FunctionNode buildFunctionNode(FunctionElement function, Node bodyNode) {
- List<ir.TypeParameter> typeParameters =
- kernel.typeParametersNotImplemented();
+ List<ir.TypeParameter> typeParameters = <ir.TypeParameter>[];
List<ir.VariableDeclaration> positionalParameters =
<ir.VariableDeclaration>[];
List<ir.VariableDeclaration> namedParameters = <ir.VariableDeclaration>[];
diff --git a/pkg/compiler/lib/src/native/enqueue.dart b/pkg/compiler/lib/src/native/enqueue.dart
index 300a650..bd37b4c 100644
--- a/pkg/compiler/lib/src/native/enqueue.dart
+++ b/pkg/compiler/lib/src/native/enqueue.dart
@@ -487,7 +487,7 @@
// Give an info so that library developers can compile with -v to find why
// all the native classes are included.
- if (unusedBefore == matchingClasses.length) {
+ if (unusedBefore > 0 && unusedBefore == matchingClasses.length) {
reporter.log('All native types marked as used due to $cause.');
}
}
diff --git a/pkg/compiler/lib/src/native/ssa.dart b/pkg/compiler/lib/src/native/ssa.dart
index 945995d..a7f185f 100644
--- a/pkg/compiler/lib/src/native/ssa.dart
+++ b/pkg/compiler/lib/src/native/ssa.dart
@@ -29,7 +29,8 @@
HInstruction local = builder.localsHandler.readLocal(parameter);
ConstantValue arityConstant =
builder.constantSystem.createInt(type.computeArity());
- HInstruction arity = builder.graph.addConstant(arityConstant, compiler);
+ HInstruction arity =
+ builder.graph.addConstant(arityConstant, builder.closedWorld);
// TODO(ngeoffray): For static methods, we could pass a method with a
// defined arity.
Element helper = backend.helpers.closureConverter;
diff --git a/pkg/compiler/lib/src/resolution/members.dart b/pkg/compiler/lib/src/resolution/members.dart
index e167b44..0c0998a 100644
--- a/pkg/compiler/lib/src/resolution/members.dart
+++ b/pkg/compiler/lib/src/resolution/members.dart
@@ -3001,7 +3001,11 @@
ResolutionResult visitSend(Send node) {
// Resolve type arguments to ensure that these are well-formed types.
- visit(node.typeArgumentsNode);
+ if (node.typeArgumentsNode != null) {
+ for (TypeAnnotation type in node.typeArgumentsNode.nodes) {
+ resolveTypeAnnotation(type, registerCheckedModeCheck: false);
+ }
+ }
if (node.isOperator) {
// `a && b`, `a + b`, `-a`, or `a is T`.
return handleOperatorSend(node);
diff --git a/pkg/compiler/lib/src/resolution/tree_elements.dart b/pkg/compiler/lib/src/resolution/tree_elements.dart
index fd0080f..f9c239c 100644
--- a/pkg/compiler/lib/src/resolution/tree_elements.dart
+++ b/pkg/compiler/lib/src/resolution/tree_elements.dart
@@ -361,9 +361,7 @@
}
void defineTarget(Node node, JumpTarget target) {
- if (_definedTargets == null) {
- _definedTargets = new Maplet<Node, JumpTarget>();
- }
+ _definedTargets ??= new Maplet<Node, JumpTarget>();
_definedTargets[node] = target;
}
@@ -382,9 +380,7 @@
}
void registerTargetOf(GotoStatement node, JumpTarget target) {
- if (_usedTargets == null) {
- _usedTargets = new Maplet<GotoStatement, JumpTarget>();
- }
+ _usedTargets ??= new Maplet<GotoStatement, JumpTarget>();
_usedTargets[node] = target;
}
@@ -394,9 +390,7 @@
}
void defineLabel(Label label, LabelDefinition target) {
- if (_definedLabels == null) {
- _definedLabels = new Maplet<Label, LabelDefinition>();
- }
+ _definedLabels ??= new Maplet<Label, LabelDefinition>();
_definedLabels[label] = target;
}
diff --git a/pkg/compiler/lib/src/serialization/resolved_ast_serialization.dart b/pkg/compiler/lib/src/serialization/resolved_ast_serialization.dart
index c839c95..3f58490 100644
--- a/pkg/compiler/lib/src/serialization/resolved_ast_serialization.dart
+++ b/pkg/compiler/lib/src/serialization/resolved_ast_serialization.dart
@@ -587,12 +587,11 @@
}
jumpTargetLabels.forEach((JumpTargetX jumpTarget, List<int> labelIds) {
if (labelIds.isEmpty) return;
- LinkBuilder<LabelDefinition> linkBuilder =
- new LinkBuilder<LabelDefinition>();
+ List<LabelDefinition> labels = <LabelDefinition>[];
for (int labelId in labelIds) {
- linkBuilder.addLast(labelDefinitions[labelId]);
+ labels.add(labelDefinitions[labelId]);
}
- jumpTarget.labels = linkBuilder.toLink();
+ jumpTarget.labels = labels;
});
ListDecoder dataDecoder = objectDecoder.getList(Key.DATA, isOptional: true);
diff --git a/pkg/compiler/lib/src/ssa/builder.dart b/pkg/compiler/lib/src/ssa/builder.dart
index cda5d75..25f7fe8 100644
--- a/pkg/compiler/lib/src/ssa/builder.dart
+++ b/pkg/compiler/lib/src/ssa/builder.dart
@@ -66,7 +66,7 @@
DiagnosticReporter get reporter => compiler.reporter;
- HGraph build(CodegenWorkItem work) {
+ HGraph build(CodegenWorkItem work, ClosedWorld closedWorld) {
return measure(() {
Element element = work.element.implementation;
return reporter.withCurrentElement(element, () {
@@ -75,6 +75,7 @@
work.resolvedAst,
work.registry,
backend,
+ closedWorld,
emitter.nativeEmitter,
sourceInformationFactory);
HGraph graph = builder.build();
@@ -91,7 +92,7 @@
work.registry.registerCompileTimeConstant(constant);
});
}
- if (compiler.tracer.isEnabled) {
+ if (backend.tracer.isEnabled) {
String name;
if (element.isClassMember) {
String className = element.enclosingClass.name;
@@ -103,8 +104,8 @@
} else {
name = "${element.name}";
}
- compiler.tracer.traceCompilation(name);
- compiler.tracer.traceGraph('builder', graph);
+ backend.tracer.traceCompilation(name);
+ backend.tracer.traceGraph('builder', graph);
}
return graph;
});
@@ -127,6 +128,7 @@
implements SemanticSendVisitor {
/// The element for which this SSA builder is being used.
final Element target;
+ final ClosedWorld closedWorld;
ResolvedAst resolvedAst;
@@ -198,6 +200,7 @@
this.resolvedAst,
this.registry,
JavaScriptBackend backend,
+ this.closedWorld,
this.nativeEmitter,
SourceInformationStrategy sourceInformationFactory)
: this.infoReporter = backend.compiler.dumpInfoTask,
@@ -576,7 +579,7 @@
instanceType: instanceType);
inlinedFrom(functionResolvedAst, () {
if (!isReachable) {
- emitReturn(graph.addConstantNull(compiler), null);
+ emitReturn(graph.addConstantNull(closedWorld), null);
} else {
doInline(functionResolvedAst);
}
@@ -637,7 +640,7 @@
backend.constants.getConstantValue(parameter.constant);
assert(invariant(parameter, constantValue != null,
message: 'No constant computed for $parameter'));
- return graph.addConstant(constantValue, compiler);
+ return graph.addConstant(constantValue, closedWorld);
}
ClassElement get currentNonClosureClass {
@@ -674,7 +677,7 @@
}
HInstruction addConstant(ast.Node node) {
- return graph.addConstant(getConstantForNode(node), compiler);
+ return graph.addConstant(getConstantForNode(node), closedWorld);
}
/**
@@ -709,12 +712,12 @@
node: function,
visitCondition: () {
HParameterValue parameter = parameters.values.first;
- push(new HIdentity(parameter, graph.addConstantNull(compiler),
+ push(new HIdentity(parameter, graph.addConstantNull(closedWorld),
null, commonMasks.boolType));
},
visitThen: () {
closeAndGotoExit(new HReturn(
- graph.addConstantBool(false, compiler),
+ graph.addConstantBool(false, closedWorld),
sourceInformationBuilder
.buildImplicitReturn(functionElement)));
},
@@ -859,7 +862,7 @@
localsHandler.closureData =
compiler.closureToClassMapper.getClosureToClassMapping(resolvedAst);
returnLocal = new SyntheticLocal("result", function);
- localsHandler.updateLocal(returnLocal, graph.addConstantNull(compiler));
+ localsHandler.updateLocal(returnLocal, graph.addConstantNull(closedWorld));
inTryStatement = false; // TODO(lry): why? Document.
@@ -984,7 +987,7 @@
for (TypeVariableType variable in typeVariables) {
localsHandler.updateLocal(
localsHandler.getTypeVariableAsLocal(variable),
- graph.addConstantNull(compiler));
+ graph.addConstantNull(closedWorld));
}
}
}
@@ -1187,7 +1190,7 @@
// Unassigned fields of native classes are not initialized to
// prevent overwriting pre-initialized native properties.
if (!backend.isNativeOrExtendsNative(classElement)) {
- fieldValues[member] = graph.addConstantNull(compiler);
+ fieldValues[member] = graph.addConstantNull(closedWorld);
}
} else {
ast.Node right = initializer;
@@ -1351,7 +1354,7 @@
if (interceptor == null) {
ConstantValue constant =
new InterceptorConstantValue(classElement.thisType);
- interceptor = graph.addConstant(constant, compiler);
+ interceptor = graph.addConstant(constant, closedWorld);
}
bodyCallInputs.add(interceptor);
}
@@ -1508,7 +1511,8 @@
if (JavaScriptBackend.TRACE_METHOD == 'post') {
if (element == backend.helpers.traceHelper) return;
// TODO(sigmund): create a better uuid for elements.
- HConstant idConstant = graph.addConstantInt(element.hashCode, compiler);
+ HConstant idConstant =
+ graph.addConstantInt(element.hashCode, closedWorld);
HConstant nameConstant = addConstantString(element.name);
add(new HInvokeStatic(backend.helpers.traceHelper,
<HInstruction>[idConstant, nameConstant], commonMasks.dynamicType));
@@ -1521,8 +1525,8 @@
localsHandler.substInContext(subtype), sourceElement);
HInstruction supertypeInstruction = typeBuilder.analyzeTypeArgument(
localsHandler.substInContext(supertype), sourceElement);
- HInstruction messageInstruction =
- graph.addConstantString(new ast.DartString.literal(message), compiler);
+ HInstruction messageInstruction = graph.addConstantString(
+ new ast.DartString.literal(message), closedWorld);
MethodElement element = helpers.assertIsSubtype;
var inputs = <HInstruction>[
subtypeInstruction,
@@ -1674,7 +1678,7 @@
HInstruction buildCondition() {
if (node.condition == null) {
- return graph.addConstantBool(true, compiler);
+ return graph.addConstantBool(true, closedWorld);
}
visit(node.condition);
return popBoolified();
@@ -1766,7 +1770,7 @@
localsHandler =
savedLocals.mergeMultiple(continueHandlers, conditionBlock);
SubGraph bodyGraph = new SubGraph(bodyEntryBlock, bodyExitBlock);
- List<LabelDefinition> labels = jumpHandler.labels();
+ List<LabelDefinition> labels = jumpHandler.labels;
HSubGraphBlockInformation bodyInfo =
new HSubGraphBlockInformation(bodyGraph);
HLabeledBlockInformation info;
@@ -1990,7 +1994,7 @@
HConstant constant = operand;
ConstantValue folded = operation.fold(constant.constant);
if (folded != null) {
- stack.add(graph.addConstant(folded, compiler));
+ stack.add(graph.addConstant(folded, closedWorld));
return;
}
}
@@ -2111,7 +2115,7 @@
assert(invariant(node, element == null || element.isMalformed));
// TODO(ahe): Do something like the above, that is, emit a runtime
// error.
- stack.add(graph.addConstantNull(compiler));
+ stack.add(graph.addConstantNull(closedWorld));
}
}
@@ -2125,10 +2129,10 @@
PrefixElement prefix =
compiler.deferredLoadTask.deferredPrefixElement(node, elements);
if (prefix != null) {
- instruction =
- graph.addDeferredConstant(value, prefix, sourceInformation, compiler);
+ instruction = graph.addDeferredConstant(
+ value, prefix, sourceInformation, compiler, closedWorld);
} else {
- instruction = graph.addConstant(value, compiler,
+ instruction = graph.addConstant(value, closedWorld,
sourceInformation: sourceInformation);
}
stack.add(instruction);
@@ -2355,7 +2359,7 @@
generateNoSuchSetter(location, element, send == null ? null : value);
} else if (Elements.isMalformed(element)) {
// TODO(ahe): Do something like [generateWrongArgumentCountError].
- stack.add(graph.addConstantNull(compiler));
+ stack.add(graph.addConstantNull(closedWorld));
} else {
stack.add(value);
LocalElement local = element;
@@ -2465,7 +2469,7 @@
HInstruction isFieldName = addConstantStringFromName(operator);
HInstruction asFieldName = closedWorld.hasAnyStrictSubtype(element)
? addConstantStringFromName(backend.namer.substitutionName(element))
- : graph.addConstantNull(compiler);
+ : graph.addConstantNull(closedWorld);
List<HInstruction> inputs = <HInstruction>[
expression,
isFieldName,
@@ -2667,7 +2671,8 @@
'text': 'Mismatch between number of placeholders'
' and number of arguments.'
});
- stack.add(graph.addConstantNull(compiler)); // Result expected on stack.
+ // Result expected on stack.
+ stack.add(graph.addConstantNull(closedWorld));
return;
}
@@ -2763,7 +2768,7 @@
reporter.reportErrorMessage(node, MessageKind.GENERIC,
{'text': 'Error: Unknown internal flag "$name".'});
}
- stack.add(graph.addConstantBool(value, compiler));
+ stack.add(graph.addConstantBool(value, closedWorld));
}
void handleForeignJsGetName(ast.Send node) {
@@ -2891,7 +2896,7 @@
if (argumentConstant is TypeConstantValue) {
ConstantValue constant =
new InterceptorConstantValue(argumentConstant.representedType);
- HInstruction instruction = graph.addConstant(constant, compiler);
+ HInstruction instruction = graph.addConstant(constant, closedWorld);
stack.add(instruction);
return;
}
@@ -2899,7 +2904,7 @@
}
reporter.reportErrorMessage(
node, MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT);
- stack.add(graph.addConstantNull(compiler));
+ stack.add(graph.addConstantNull(closedWorld));
}
void handleForeignJsCallInIsolate(ast.Send node) {
@@ -3011,7 +3016,7 @@
} else if (name == 'JS_GET_FLAG') {
handleForeignJsGetFlag(node);
} else if (name == 'JS_EFFECT') {
- stack.add(graph.addConstantNull(compiler));
+ stack.add(graph.addConstantNull(closedWorld));
} else if (name == BackendHelpers.JS_INTERCEPTOR_CONSTANT) {
handleJsInterceptorConstant(node);
} else if (name == 'JS_STRING_CONCAT') {
@@ -3030,7 +3035,7 @@
String loadId =
compiler.deferredLoadTask.getImportDeferName(node, prefixElement);
var inputs = [
- graph.addConstantString(new ast.DartString.literal(loadId), compiler)
+ graph.addConstantString(new ast.DartString.literal(loadId), closedWorld)
];
push(new HInvokeStatic(loadFunction, inputs, commonMasks.nonNullType,
targetCanThrow: false)..sourceInformation = sourceInformation);
@@ -3069,7 +3074,7 @@
for (String argumentName in selector.namedArguments) {
ConstantValue argumentNameConstant =
constantSystem.createString(new ast.DartString.literal(argumentName));
- argumentNames.add(graph.addConstant(argumentNameConstant, compiler));
+ argumentNames.add(graph.addConstant(argumentNameConstant, closedWorld));
}
var argumentNamesInstruction = buildLiteralList(argumentNames);
add(argumentNamesInstruction);
@@ -3081,9 +3086,9 @@
null,
createInvocationMirror,
[
- graph.addConstant(nameConstant, compiler),
- graph.addConstantStringFromName(internalName, compiler),
- graph.addConstant(kindConstant, compiler),
+ graph.addConstant(nameConstant, closedWorld),
+ graph.addConstantStringFromName(internalName, closedWorld),
+ graph.addConstant(kindConstant, closedWorld),
argumentsInstruction,
argumentNamesInstruction
],
@@ -3396,7 +3401,7 @@
if (compiler.elementHasCompileTimeError(constructor)) {
// TODO(ahe): Do something like [generateWrongArgumentCountError].
- stack.add(graph.addConstantNull(compiler));
+ stack.add(graph.addConstantNull(closedWorld));
return;
}
@@ -3431,7 +3436,7 @@
backend.isNativeOrExtendsNative(constructor.enclosingClass) &&
!backend.isJsInterop(constructor)) {
// Native class generative constructors take a pre-constructed object.
- inputs.add(graph.addConstantNull(compiler));
+ inputs.add(graph.addConstantNull(closedWorld));
}
inputs.addAll(makeStaticArgumentList(
callStructure, send.arguments, constructorImplementation));
@@ -3721,18 +3726,18 @@
handleInvalidStaticInvoke(node, element);
} else {
// TODO(ahe): Do something like [generateWrongArgumentCountError].
- stack.add(graph.addConstantNull(compiler));
+ stack.add(graph.addConstantNull(closedWorld));
}
return;
}
HConstant addConstantString(String string) {
ast.DartString dartString = new ast.DartString.literal(string);
- return graph.addConstantString(dartString, compiler);
+ return graph.addConstantString(dartString, closedWorld);
}
HConstant addConstantStringFromName(js.Name name) {
- return graph.addConstantStringFromName(name, compiler);
+ return graph.addConstantStringFromName(name, closedWorld);
}
visitClassTypeLiteralGet(ast.Send node, ConstantExpression constant, _) {
@@ -3862,10 +3867,10 @@
Element helper = helpers.throwNoSuchMethod;
ConstantValue receiverConstant =
constantSystem.createString(new ast.DartString.empty());
- HInstruction receiver = graph.addConstant(receiverConstant, compiler);
+ HInstruction receiver = graph.addConstant(receiverConstant, closedWorld);
ast.DartString dartString = new ast.DartString.literal(methodName);
ConstantValue nameConstant = constantSystem.createString(dartString);
- HInstruction name = graph.addConstant(nameConstant, compiler);
+ HInstruction name = graph.addConstant(nameConstant, closedWorld);
if (argumentValues == null) {
argumentValues = <HInstruction>[];
argumentNodes.forEach((argumentNode) {
@@ -3880,14 +3885,14 @@
if (existingArguments != null) {
List<HInstruction> existingNames = <HInstruction>[];
for (String name in existingArguments) {
- HInstruction nameConstant =
- graph.addConstantString(new ast.DartString.literal(name), compiler);
+ HInstruction nameConstant = graph.addConstantString(
+ new ast.DartString.literal(name), closedWorld);
existingNames.add(nameConstant);
}
existingNamesList = buildLiteralList(existingNames);
add(existingNamesList);
} else {
- existingNamesList = graph.addConstantNull(compiler);
+ existingNamesList = graph.addConstantNull(closedWorld);
}
pushInvokeStatic(
diagnosticNode, helper, [receiver, name, arguments, existingNamesList],
@@ -3938,7 +3943,7 @@
}
} else if (Elements.isMalformed(element)) {
// TODO(ahe): Do something like [generateWrongArgumentCountError].
- stack.add(graph.addConstantNull(compiler));
+ stack.add(graph.addConstantNull(closedWorld));
} else if (node.isConst) {
stack.add(addConstant(node));
if (isSymbolConstructor) {
@@ -4206,7 +4211,7 @@
ast.SendSet node, HInstruction receiver, Link<ast.Node> arguments) {
HInstruction rhs;
if (node.isPrefix || node.isPostfix) {
- rhs = graph.addConstantInt(1, compiler);
+ rhs = graph.addConstantInt(1, closedWorld);
} else {
visit(arguments.head);
assert(arguments.tail.isEmpty);
@@ -4966,19 +4971,19 @@
}
void visitLiteralInt(ast.LiteralInt node) {
- stack.add(graph.addConstantInt(node.value, compiler));
+ stack.add(graph.addConstantInt(node.value, closedWorld));
}
void visitLiteralDouble(ast.LiteralDouble node) {
- stack.add(graph.addConstantDouble(node.value, compiler));
+ stack.add(graph.addConstantDouble(node.value, closedWorld));
}
void visitLiteralBool(ast.LiteralBool node) {
- stack.add(graph.addConstantBool(node.value, compiler));
+ stack.add(graph.addConstantBool(node.value, closedWorld));
}
void visitLiteralString(ast.LiteralString node) {
- stack.add(graph.addConstantString(node.dartString, compiler));
+ stack.add(graph.addConstantString(node.dartString, closedWorld));
}
void visitLiteralSymbol(ast.LiteralSymbol node) {
@@ -4989,7 +4994,7 @@
void visitStringJuxtaposition(ast.StringJuxtaposition node) {
if (!node.isInterpolation) {
// This is a simple string with no interpolations.
- stack.add(graph.addConstantString(node.dartString, compiler));
+ stack.add(graph.addConstantString(node.dartString, closedWorld));
return;
}
StringBuilderVisitor stringBuilder = new StringBuilderVisitor(this, node);
@@ -4998,7 +5003,7 @@
}
void visitLiteralNull(ast.LiteralNull node) {
- stack.add(graph.addConstantNull(compiler));
+ stack.add(graph.addConstantNull(closedWorld));
}
visitNodeList(ast.NodeList node) {
@@ -5044,7 +5049,7 @@
visitRethrow(ast.Rethrow node) {
HInstruction exception = rethrowableException;
if (exception == null) {
- exception = graph.addConstantNull(compiler);
+ exception = graph.addConstantNull(closedWorld);
reporter.internalError(node, 'rethrowableException should not be null.');
}
handleInTryStatement();
@@ -5089,7 +5094,7 @@
inputs.add(handleConstantForOptionalParameter(optionalParameter));
} else {
// Wrong.
- inputs.add(graph.addConstantNull(compiler));
+ inputs.add(graph.addConstantNull(closedWorld));
}
}
@@ -5160,7 +5165,7 @@
}
HInstruction value;
if (node.expression == null) {
- value = graph.addConstantNull(compiler);
+ value = graph.addConstantNull(closedWorld);
} else {
visit(node.expression);
value = pop();
@@ -5218,7 +5223,7 @@
ast.Node definition = link.head;
LocalElement local = elements[definition];
if (definition is ast.Identifier) {
- HInstruction initialValue = graph.addConstantNull(compiler);
+ HInstruction initialValue = graph.addConstantNull(closedWorld);
localsHandler.updateLocal(local, initialValue);
} else {
ast.SendSet node = definition;
@@ -5357,7 +5362,7 @@
visit(node.expression);
HInstruction expression = pop();
pushInvokeStatic(node, helpers.streamIteratorConstructor,
- [expression, graph.addConstantNull(compiler)]);
+ [expression, graph.addConstantNull(closedWorld)]);
streamIterator = pop();
void buildInitializer() {}
@@ -5533,9 +5538,9 @@
void buildInitializer() {
visit(node.expression);
array = pop();
- isFixed = isFixedLength(array.instructionType, compiler);
+ isFixed = isFixedLength(array.instructionType, closedWorld);
localsHandler.updateLocal(
- indexVariable, graph.addConstantInt(0, compiler));
+ indexVariable, graph.addConstantInt(0, closedWorld));
originalLength = buildGetLength();
}
@@ -5579,7 +5584,7 @@
// but the code is horrible as `i+1` is carried around the loop in an
// additional variable.
HInstruction index = localsHandler.readLocal(indexVariable);
- HInstruction one = graph.addConstantInt(1, compiler);
+ HInstruction one = graph.addConstantInt(1, closedWorld);
HInstruction addInstruction =
new HAdd(index, one, null, commonMasks.positiveIntType);
add(addInstruction);
@@ -5630,7 +5635,7 @@
// There was at least one reachable break, so the label is needed.
entryBlock.setBlockFlow(
new HLabeledBlockInformation(
- new HSubGraphBlockInformation(bodyGraph), handler.labels()),
+ new HSubGraphBlockInformation(bodyGraph), handler.labels),
joinBlock);
}
handler.close();
@@ -5848,7 +5853,7 @@
// }
JumpTarget switchTarget = elements.getTargetDefinition(node);
- HInstruction initialValue = graph.addConstantNull(compiler);
+ HInstruction initialValue = graph.addConstantNull(closedWorld);
localsHandler.updateLocal(switchTarget, initialValue);
JumpHandler jumpHandler = createJumpHandler(node, isLoopJump: false);
@@ -5884,11 +5889,11 @@
if (switchCase != null) {
// Generate 'target = i; break;' for switch case i.
int index = caseIndex[switchCase];
- HInstruction value = graph.addConstantInt(index, compiler);
+ HInstruction value = graph.addConstantInt(index, closedWorld);
localsHandler.updateLocal(switchTarget, value);
} else {
// Generate synthetic default case 'target = null; break;'.
- HInstruction value = graph.addConstantNull(compiler);
+ HInstruction value = graph.addConstantNull(closedWorld);
localsHandler.updateLocal(switchTarget, value);
}
jumpTargets[switchTarget].generateBreak();
@@ -5898,7 +5903,7 @@
isDefaultCase, buildSwitchCase);
jumpHandler.close();
- HInstruction buildCondition() => graph.addConstantBool(true, compiler);
+ HInstruction buildCondition() => graph.addConstantBool(true, closedWorld);
void buildSwitch() {
HInstruction buildExpression() {
@@ -5993,7 +5998,7 @@
ast.SwitchCase switchCase = caseIterator.next();
HBasicBlock block = graph.addNewBlock();
for (ConstantValue constant in getConstants(switchCase)) {
- HConstant hConstant = graph.addConstant(constant, compiler);
+ HConstant hConstant = graph.addConstant(constant, closedWorld);
switchInstruction.inputs.add(hConstant);
hConstant.usedBy.add(switchInstruction);
expressionEnd.addSuccessor(block);
@@ -6076,8 +6081,8 @@
new HSubExpressionBlockInformation(
new SubExpression(expressionStart, expressionEnd));
expressionStart.setBlockFlow(
- new HSwitchBlockInformation(expressionInfo, statements,
- jumpHandler.target, jumpHandler.labels()),
+ new HSwitchBlockInformation(
+ expressionInfo, statements, jumpHandler.target, jumpHandler.labels),
joinBlock);
jumpHandler.close();
@@ -6248,7 +6253,7 @@
ast.VariableDefinitions declaration = catchBlock.formals.nodes.head;
HInstruction condition = null;
if (declaration.type == null) {
- condition = graph.addConstantBool(true, compiler);
+ condition = graph.addConstantBool(true, closedWorld);
stack.add(condition);
} else {
// TODO(aprelev@gmail.com): Once old catch syntax is removed
diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart
index c02f096..7c92668 100644
--- a/pkg/compiler/lib/src/ssa/builder_kernel.dart
+++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
@@ -3,7 +3,6 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:kernel/ast.dart' as ir;
-import 'package:kernel/text/ast_to_text.dart' show debugNodeToString;
import '../closure.dart';
import '../common.dart';
@@ -26,14 +25,15 @@
import '../native/native.dart' as native;
import '../resolution/tree_elements.dart';
import '../tree/dartstring.dart';
-import '../tree/nodes.dart' show FunctionExpression, Node;
+import '../tree/nodes.dart' show Node, BreakStatement;
import '../types/masks.dart';
import '../universe/call_structure.dart' show CallStructure;
import '../universe/selector.dart';
-import '../universe/use.dart' show StaticUse, TypeUse;
import '../universe/side_effects.dart' show SideEffects;
-import '../world.dart' show ClosedWorld;
+import '../universe/use.dart' show StaticUse;
+import '../world.dart';
import 'graph_builder.dart';
+import 'jump_handler.dart';
import 'kernel_ast_adapter.dart';
import 'kernel_string_builder.dart';
import 'locals_handler.dart';
@@ -53,15 +53,21 @@
: backend = backend,
super(backend.compiler.measurer);
- HGraph build(CodegenWorkItem work) {
+ HGraph build(CodegenWorkItem work, ClosedWorld closedWorld) {
return measure(() {
AstElement element = work.element.implementation;
Kernel kernel = backend.kernelTask.kernel;
- KernelSsaBuilder builder = new KernelSsaBuilder(element, work.resolvedAst,
- backend.compiler, work.registry, sourceInformationFactory, kernel);
+ KernelSsaBuilder builder = new KernelSsaBuilder(
+ element,
+ work.resolvedAst,
+ backend.compiler,
+ closedWorld,
+ work.registry,
+ sourceInformationFactory,
+ kernel);
HGraph graph = builder.build();
- if (backend.compiler.tracer.isEnabled) {
+ if (backend.tracer.isEnabled) {
String name;
if (element.isClassMember) {
String className = element.enclosingClass.name;
@@ -73,8 +79,8 @@
} else {
name = "${element.name}";
}
- backend.compiler.tracer.traceCompilation(name);
- backend.compiler.tracer.traceGraph('builder', graph);
+ backend.tracer.traceCompilation(name);
+ backend.tracer.traceGraph('builder', graph);
}
return graph;
@@ -86,6 +92,7 @@
ir.Node target;
final AstElement targetElement;
final ResolvedAst resolvedAst;
+ final ClosedWorld closedWorld;
final CodegenRegistry registry;
/// Helper accessor for all kernel function-like targets (Procedure,
@@ -126,6 +133,7 @@
this.targetElement,
this.resolvedAst,
Compiler compiler,
+ this.closedWorld,
this.registry,
SourceInformationStrategy sourceInformationFactory,
Kernel kernel) {
@@ -192,7 +200,7 @@
fieldValue, astAdapter.getDartType(field.type));
stack.add(checkInstruction);
} else {
- stack.add(graph.addConstantNull(compiler));
+ stack.add(graph.addConstantNull(closedWorld));
}
HInstruction value = pop();
closeAndGotoExit(new HReturn(value, null));
@@ -267,7 +275,7 @@
for (var field in clazz.fields) {
if (field.initializer == null) {
- fieldValues[field] = graph.addConstantNull(compiler);
+ fieldValues[field] = graph.addConstantNull(closedWorld);
} else {
field.initializer.accept(this);
fieldValues[field] = pop();
@@ -332,7 +340,7 @@
backend.constants.getConstantValue(element.constant);
assert(invariant(element, constantValue != null,
message: 'No constant computed for $element'));
- builtArguments.add(graph.addConstant(constantValue, compiler));
+ builtArguments.add(graph.addConstant(constantValue, closedWorld));
}
});
} else {
@@ -348,7 +356,7 @@
backend.constants.getConstantValue(element.constant);
assert(invariant(element, constantValue != null,
message: 'No constant computed for $element'));
- builtArguments.add(graph.addConstant(constantValue, compiler));
+ builtArguments.add(graph.addConstant(constantValue, closedWorld));
}
});
}
@@ -428,7 +436,7 @@
/// Pushes a boolean checking [expression] against null.
pushCheckNull(HInstruction expression) {
- push(new HIdentity(expression, graph.addConstantNull(compiler), null,
+ push(new HIdentity(expression, graph.addConstantNull(closedWorld), null,
commonMasks.boolType));
}
@@ -445,9 +453,9 @@
}
void _trap(String message) {
- HInstruction nullValue = graph.addConstantNull(compiler);
+ HInstruction nullValue = graph.addConstantNull(closedWorld);
HInstruction errorMessage =
- graph.addConstantString(new DartString.literal(message), compiler);
+ graph.addConstantString(new DartString.literal(message), closedWorld);
HInstruction trap = new HForeignCode(js.js.parseForeignJS("#.#"),
commonMasks.dynamicType, <HInstruction>[nullValue, errorMessage]);
trap.sideEffects
@@ -507,7 +515,7 @@
void visitReturnStatement(ir.ReturnStatement returnStatement) {
HInstruction value;
if (returnStatement.expression == null) {
- value = graph.addConstantNull(compiler);
+ value = graph.addConstantNull(closedWorld);
} else {
assert(_targetFunction != null && _targetFunction is ir.FunctionNode);
returnStatement.expression.accept(this);
@@ -532,7 +540,7 @@
HInstruction buildCondition() {
if (forStatement.condition == null) {
- return graph.addConstantBool(true, compiler);
+ return graph.addConstantBool(true, closedWorld);
}
forStatement.condition.accept(this);
return popBoolified();
@@ -564,7 +572,7 @@
}
// If the expression being iterated over is a JS indexable type, we can
// generate an optimized version of for-in that uses indexing.
- if (astAdapter.isJsIndexableIterator(forInStatement)) {
+ if (astAdapter.isJsIndexableIterator(forInStatement, closedWorld)) {
_buildForInIndexable(forInStatement);
} else {
_buildForInIterator(forInStatement);
@@ -617,9 +625,9 @@
void buildInitializer() {
forInStatement.iterable.accept(this);
array = pop();
- isFixed = astAdapter.isFixedLength(array.instructionType);
+ isFixed = astAdapter.isFixedLength(array.instructionType, closedWorld);
localsHandler.updateLocal(
- indexVariable, graph.addConstantInt(0, compiler));
+ indexVariable, graph.addConstantInt(0, closedWorld));
originalLength = buildGetLength();
}
@@ -664,7 +672,7 @@
// but the code is horrible as `i+1` is carried around the loop in an
// additional variable.
HInstruction index = localsHandler.readLocal(indexVariable);
- HInstruction one = graph.addConstantInt(1, compiler);
+ HInstruction one = graph.addConstantInt(1, closedWorld);
HInstruction addInstruction =
new HAdd(index, one, null, commonMasks.positiveIntType);
add(addInstruction);
@@ -783,7 +791,7 @@
void generateError(ir.Node node, String message, TypeMask typeMask) {
HInstruction errorMessage =
- graph.addConstantString(new DartString.literal(message), compiler);
+ graph.addConstantString(new DartString.literal(message), closedWorld);
_pushStaticInvocation(node, [errorMessage], typeMask);
}
@@ -820,6 +828,59 @@
}
@override
+ void visitBreakStatement(ir.BreakStatement breakStatement) {
+ assert(!isAborted());
+ JumpTarget target = astAdapter.getJumpTarget(breakStatement.target);
+ assert(target != null);
+ JumpHandler handler = jumpTargets[target];
+ assert(handler != null);
+ handler.generateBreak(handler.labels.first);
+ }
+
+ @override
+ void visitLabeledStatement(ir.LabeledStatement labeledStatement) {
+ JumpTarget target = astAdapter.getJumpTarget(labeledStatement);
+ JumpHandler handler = new JumpHandler(this, target);
+
+ ir.Statement body = labeledStatement.body;
+ if (body is ir.WhileStatement ||
+ body is ir.DoStatement ||
+ body is ir.ForStatement ||
+ body is ir.ForInStatement) {
+ // loops handle breaks on their own
+ body.accept(this);
+ return;
+ }
+ LocalsHandler beforeLocals = new LocalsHandler.from(localsHandler);
+
+ HBasicBlock newBlock = openNewBlock();
+ body.accept(this);
+ SubGraph bodyGraph = new SubGraph(newBlock, lastOpenedBlock);
+
+ HBasicBlock joinBlock = graph.addNewBlock();
+ List<LocalsHandler> breakHandlers = <LocalsHandler>[];
+ handler.forEachBreak((HBreak breakInstruction, LocalsHandler locals) {
+ breakInstruction.block.addSuccessor(joinBlock);
+ breakHandlers.add(locals);
+ });
+
+ if (!isAborted()) {
+ goto(current, joinBlock);
+ breakHandlers.add(localsHandler);
+ }
+
+ open(joinBlock);
+ localsHandler = beforeLocals.mergeMultiple(breakHandlers, joinBlock);
+
+ // There was at least one reachable break, so the label is needed.
+ newBlock.setBlockFlow(
+ new HLabeledBlockInformation(
+ new HSubGraphBlockInformation(bodyGraph), handler.labels),
+ joinBlock);
+ handler.close();
+ }
+
+ @override
void visitConditionalExpression(ir.ConditionalExpression conditional) {
SsaBranchBuilder brancher = new SsaBranchBuilder(this, compiler);
brancher.handleConditional(
@@ -838,35 +899,35 @@
@override
void visitIntLiteral(ir.IntLiteral intLiteral) {
- stack.add(graph.addConstantInt(intLiteral.value, compiler));
+ stack.add(graph.addConstantInt(intLiteral.value, closedWorld));
}
@override
void visitDoubleLiteral(ir.DoubleLiteral doubleLiteral) {
- stack.add(graph.addConstantDouble(doubleLiteral.value, compiler));
+ stack.add(graph.addConstantDouble(doubleLiteral.value, closedWorld));
}
@override
void visitBoolLiteral(ir.BoolLiteral boolLiteral) {
- stack.add(graph.addConstantBool(boolLiteral.value, compiler));
+ stack.add(graph.addConstantBool(boolLiteral.value, closedWorld));
}
@override
void visitStringLiteral(ir.StringLiteral stringLiteral) {
stack.add(graph.addConstantString(
- new DartString.literal(stringLiteral.value), compiler));
+ new DartString.literal(stringLiteral.value), closedWorld));
}
@override
void visitSymbolLiteral(ir.SymbolLiteral symbolLiteral) {
stack.add(graph.addConstant(
- astAdapter.getConstantForSymbol(symbolLiteral), compiler));
+ astAdapter.getConstantForSymbol(symbolLiteral), closedWorld));
registry?.registerConstSymbol(symbolLiteral.value);
}
@override
void visitNullLiteral(ir.NullLiteral nullLiteral) {
- stack.add(graph.addConstantNull(compiler));
+ stack.add(graph.addConstantNull(closedWorld));
}
/// Set the runtime type information if necessary.
@@ -890,8 +951,8 @@
void visitListLiteral(ir.ListLiteral listLiteral) {
HInstruction listInstruction;
if (listLiteral.isConst) {
- listInstruction =
- graph.addConstant(astAdapter.getConstantFor(listLiteral), compiler);
+ listInstruction = graph.addConstant(
+ astAdapter.getConstantFor(listLiteral), closedWorld);
} else {
List<HInstruction> elements = <HInstruction>[];
for (ir.Expression element in listLiteral.expressions) {
@@ -905,7 +966,8 @@
setListRuntimeTypeInfoIfNeeded(listInstruction, listLiteral);
}
- TypeMask type = astAdapter.typeOfListLiteral(targetElement, listLiteral);
+ TypeMask type =
+ astAdapter.typeOfListLiteral(targetElement, listLiteral, closedWorld);
if (!type.containsAll(closedWorld)) {
listInstruction.instructionType = type;
}
@@ -915,8 +977,8 @@
@override
void visitMapLiteral(ir.MapLiteral mapLiteral) {
if (mapLiteral.isConst) {
- stack.add(
- graph.addConstant(astAdapter.getConstantFor(mapLiteral), compiler));
+ stack.add(graph.addConstant(
+ astAdapter.getConstantFor(mapLiteral), closedWorld));
return;
}
@@ -1001,7 +1063,7 @@
ir.DartType type = typeLiteral.type;
if (type is ir.InterfaceType) {
ConstantValue constant = astAdapter.getConstantForType(type);
- stack.add(graph.addConstant(constant, compiler));
+ stack.add(graph.addConstant(constant, closedWorld));
return;
}
if (type is ir.TypeParameterType) {
@@ -1033,7 +1095,7 @@
} else if (staticTarget is ir.Field && staticTarget.isConst) {
assert(staticTarget.initializer != null);
stack.add(graph.addConstant(
- astAdapter.getConstantFor(staticTarget.initializer), compiler));
+ astAdapter.getConstantFor(staticTarget.initializer), closedWorld));
} else {
if (_isLazyStatic(staticTarget)) {
push(new HLazyStatic(astAdapter.getField(staticTarget),
@@ -1098,7 +1160,9 @@
propertySet.value.accept(this);
HInstruction value = pop();
- _pushDynamicInvocation(propertySet, astAdapter.typeOfSet(propertySet),
+ _pushDynamicInvocation(
+ propertySet,
+ astAdapter.typeOfSet(propertySet, closedWorld),
<HInstruction>[receiver, value]);
pop();
@@ -1116,7 +1180,7 @@
void visitVariableDeclaration(ir.VariableDeclaration declaration) {
Local local = astAdapter.getLocal(declaration);
if (declaration.initializer == null) {
- HInstruction initialValue = graph.addConstantNull(compiler);
+ HInstruction initialValue = graph.addConstantNull(closedWorld);
localsHandler.updateLocal(local, initialValue);
} else {
declaration.initializer.accept(this);
@@ -1231,12 +1295,12 @@
HInstruction _defaultValueForParameter(ir.VariableDeclaration parameter) {
ir.Expression initializer = parameter.initializer;
- if (initializer == null) return graph.addConstantNull(compiler);
+ if (initializer == null) return graph.addConstantNull(closedWorld);
// TODO(sra): Evaluate constant in ir.Node domain.
ConstantValue constant =
astAdapter.getConstantForParameterDefaultValue(initializer);
- if (constant == null) return graph.addConstantNull(compiler);
- return graph.addConstant(constant, compiler);
+ if (constant == null) return graph.addConstantNull(closedWorld);
+ return graph.addConstant(constant, closedWorld);
}
@override
@@ -1282,7 +1346,7 @@
} else if (name == 'JS_GET_FLAG') {
handleForeignJsGetFlag(invocation);
} else if (name == 'JS_EFFECT') {
- stack.add(graph.addConstantNull(compiler));
+ stack.add(graph.addConstantNull(closedWorld));
} else if (name == 'JS_INTERCEPTOR_CONSTANT') {
handleJsInterceptorConstant(invocation);
} else if (name == 'JS_STRING_CONCAT') {
@@ -1368,7 +1432,8 @@
void handleForeignJsCurrentIsolateContext(ir.StaticInvocation invocation) {
if (_unexpectedForeignArguments(invocation, 0, 0)) {
- stack.add(graph.addConstantNull(compiler)); // Result expected on stack.
+ // Result expected on stack.
+ stack.add(graph.addConstantNull(closedWorld));
return;
}
@@ -1394,7 +1459,8 @@
void handleForeignJsCallInIsolate(ir.StaticInvocation invocation) {
if (_unexpectedForeignArguments(invocation, 2, 2)) {
- stack.add(graph.addConstantNull(compiler)); // Result expected on stack.
+ // Result expected on stack.
+ stack.add(graph.addConstantNull(closedWorld));
return;
}
@@ -1426,7 +1492,8 @@
void handleForeignRawFunctionRef(
ir.StaticInvocation invocation, String name) {
if (_unexpectedForeignArguments(invocation, 1, 1)) {
- stack.add(graph.addConstantNull(compiler)); // Result expected on stack.
+ // Result expected on stack.
+ stack.add(graph.addConstantNull(closedWorld));
return;
}
@@ -1458,13 +1525,14 @@
compiler.reporter.reportErrorMessage(astAdapter.getNode(invocation),
MessageKind.GENERIC, {'text': "'$name' $problem."});
- stack.add(graph.addConstantNull(compiler)); // Result expected on stack.
+ stack.add(graph.addConstantNull(closedWorld)); // Result expected on stack.
return;
}
void handleForeignJsSetStaticState(ir.StaticInvocation invocation) {
if (_unexpectedForeignArguments(invocation, 1, 1)) {
- stack.add(graph.addConstantNull(compiler)); // Result expected on stack.
+ // Result expected on stack.
+ stack.add(graph.addConstantNull(closedWorld));
return;
}
@@ -1481,7 +1549,8 @@
void handleForeignJsGetStaticState(ir.StaticInvocation invocation) {
if (_unexpectedForeignArguments(invocation, 0, 0)) {
- stack.add(graph.addConstantNull(compiler)); // Result expected on stack.
+ // Result expected on stack.
+ stack.add(graph.addConstantNull(closedWorld));
return;
}
@@ -1492,7 +1561,8 @@
void handleForeignJsGetName(ir.StaticInvocation invocation) {
if (_unexpectedForeignArguments(invocation, 1, 1)) {
- stack.add(graph.addConstantNull(compiler)); // Result expected on stack.
+ // Result expected on stack.
+ stack.add(graph.addConstantNull(closedWorld));
return;
}
@@ -1503,7 +1573,7 @@
if (instruction is HConstant) {
js.Name name =
astAdapter.getNameForJsGetName(argument, instruction.constant);
- stack.add(graph.addConstantStringFromName(name, compiler));
+ stack.add(graph.addConstantStringFromName(name, closedWorld));
return;
}
@@ -1511,12 +1581,14 @@
astAdapter.getNode(argument),
MessageKind.GENERIC,
{'text': 'Error: Expected a JsGetName enum value.'});
- stack.add(graph.addConstantNull(compiler)); // Result expected on stack.
+ // Result expected on stack.
+ stack.add(graph.addConstantNull(closedWorld));
}
void handleForeignJsEmbeddedGlobal(ir.StaticInvocation invocation) {
if (_unexpectedForeignArguments(invocation, 2, 2)) {
- stack.add(graph.addConstantNull(compiler)); // Result expected on stack.
+ // Result expected on stack.
+ stack.add(graph.addConstantNull(closedWorld));
return;
}
String globalName = _foreignConstantStringArgument(
@@ -1529,14 +1601,16 @@
assert(invariant(astAdapter.getNode(invocation), nativeBehavior != null,
message: "No NativeBehavior for $invocation"));
- TypeMask ssaType = astAdapter.typeFromNativeBehavior(nativeBehavior);
+ TypeMask ssaType =
+ astAdapter.typeFromNativeBehavior(nativeBehavior, closedWorld);
push(new HForeignCode(expr, ssaType, const <HInstruction>[],
nativeBehavior: nativeBehavior));
}
void handleForeignJsBuiltin(ir.StaticInvocation invocation) {
if (_unexpectedForeignArguments(invocation, 2)) {
- stack.add(graph.addConstantNull(compiler)); // Result expected on stack.
+ // Result expected on stack.
+ stack.add(graph.addConstantNull(closedWorld));
return;
}
@@ -1555,7 +1629,8 @@
astAdapter.getNode(nameArgument),
MessageKind.GENERIC,
{'text': 'Error: Expected a JsBuiltin enum value.'});
- stack.add(graph.addConstantNull(compiler)); // Result expected on stack.
+ // Result expected on stack.
+ stack.add(graph.addConstantNull(closedWorld));
return;
}
@@ -1570,7 +1645,8 @@
assert(invariant(astAdapter.getNode(invocation), nativeBehavior != null,
message: "No NativeBehavior for $invocation"));
- TypeMask ssaType = astAdapter.typeFromNativeBehavior(nativeBehavior);
+ TypeMask ssaType =
+ astAdapter.typeFromNativeBehavior(nativeBehavior, closedWorld);
push(new HForeignCode(template, ssaType, inputs,
nativeBehavior: nativeBehavior));
}
@@ -1578,7 +1654,8 @@
void handleForeignJsGetFlag(ir.StaticInvocation invocation) {
if (_unexpectedForeignArguments(invocation, 1, 1)) {
stack.add(
- graph.addConstantBool(false, compiler)); // Result expected on stack.
+ // Result expected on stack.
+ graph.addConstantBool(false, closedWorld));
return;
}
String name = _foreignConstantStringArgument(invocation, 0, 'JS_GET_FLAG');
@@ -1596,14 +1673,15 @@
MessageKind.GENERIC,
{'text': 'Error: Unknown internal flag "$name".'});
}
- stack.add(graph.addConstantBool(value, compiler));
+ stack.add(graph.addConstantBool(value, closedWorld));
}
void handleJsInterceptorConstant(ir.StaticInvocation invocation) {
// Single argument must be a TypeConstant which is converted into a
// InterceptorConstant.
if (_unexpectedForeignArguments(invocation, 1, 1)) {
- stack.add(graph.addConstantNull(compiler)); // Result expected on stack.
+ // Result expected on stack.
+ stack.add(graph.addConstantNull(closedWorld));
return;
}
ir.Expression argument = invocation.arguments.positional.single;
@@ -1615,7 +1693,7 @@
// TODO(sra): Check that type is a subclass of [Interceptor].
ConstantValue constant =
new InterceptorConstantValue(argumentConstant.representedType);
- HInstruction instruction = graph.addConstant(constant, compiler);
+ HInstruction instruction = graph.addConstant(constant, closedWorld);
stack.add(instruction);
return;
}
@@ -1623,12 +1701,13 @@
compiler.reporter.reportErrorMessage(astAdapter.getNode(invocation),
MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT);
- stack.add(graph.addConstantNull(compiler));
+ stack.add(graph.addConstantNull(closedWorld));
}
void handleForeignJs(ir.StaticInvocation invocation) {
if (_unexpectedForeignArguments(invocation, 2)) {
- stack.add(graph.addConstantNull(compiler)); // Result expected on stack.
+ // Result expected on stack.
+ stack.add(graph.addConstantNull(closedWorld));
return;
}
@@ -1649,7 +1728,8 @@
'text': 'Mismatch between number of placeholders'
' and number of arguments.'
});
- stack.add(graph.addConstantNull(compiler)); // Result expected on stack.
+ // Result expected on stack.
+ stack.add(graph.addConstantNull(closedWorld));
return;
}
@@ -1658,7 +1738,8 @@
astAdapter.getNode(invocation), MessageKind.JS_PLACEHOLDER_CAPTURE);
}
- TypeMask ssaType = astAdapter.typeFromNativeBehavior(nativeBehavior);
+ TypeMask ssaType =
+ astAdapter.typeFromNativeBehavior(nativeBehavior, closedWorld);
SourceInformation sourceInformation = null;
push(new HForeignCode(nativeBehavior.codeTemplate, ssaType, inputs,
@@ -1669,7 +1750,8 @@
void handleJsStringConcat(ir.StaticInvocation invocation) {
if (_unexpectedForeignArguments(invocation, 2, 2)) {
- stack.add(graph.addConstantNull(compiler)); // Result expected on stack.
+ // Result expected on stack.
+ stack.add(graph.addConstantNull(closedWorld));
return;
}
List<HInstruction> inputs = _visitPositionalArguments(invocation.arguments);
@@ -1680,12 +1762,12 @@
ir.Node target, List<HInstruction> arguments, TypeMask typeMask) {
HInvokeStatic instruction = new HInvokeStatic(
astAdapter.getMember(target), arguments, typeMask,
- targetCanThrow: astAdapter.getCanThrow(target));
+ targetCanThrow: astAdapter.getCanThrow(target, closedWorld));
if (currentImplicitInstantiations.isNotEmpty) {
instruction.instantiatedTypes =
new List<DartType>.from(currentImplicitInstantiations);
}
- instruction.sideEffects = astAdapter.getSideEffects(target);
+ instruction.sideEffects = astAdapter.getSideEffects(target, closedWorld);
push(instruction);
}
@@ -1771,7 +1853,7 @@
Selector selector = astAdapter.getSelector(invocation);
_pushDynamicInvocation(
invocation,
- astAdapter.typeOfInvocation(invocation),
+ astAdapter.typeOfInvocation(invocation, closedWorld),
<HInstruction>[receiver]
..addAll(
_visitArgumentsForDynamicTarget(selector, invocation.arguments)));
@@ -1867,7 +1949,7 @@
type = localsHandler.substInContext(type).unaliased;
if (type is MethodTypeVariableType) {
- return graph.addConstantBool(true, compiler);
+ return graph.addConstantBool(true, closedWorld);
}
if (type is MalformedType) {
@@ -2124,8 +2206,8 @@
catchBlock.exception, catchBlock.guard, unwrappedException);
kernelBuilder.push(condition);
} else {
- kernelBuilder.stack.add(
- kernelBuilder.graph.addConstantBool(true, kernelBuilder.compiler));
+ kernelBuilder.stack.add(kernelBuilder.graph
+ .addConstantBool(true, kernelBuilder.closedWorld));
}
}
diff --git a/pkg/compiler/lib/src/ssa/codegen.dart b/pkg/compiler/lib/src/ssa/codegen.dart
index 98ccfb1..bf90d8e 100644
--- a/pkg/compiler/lib/src/ssa/codegen.dart
+++ b/pkg/compiler/lib/src/ssa/codegen.dart
@@ -59,36 +59,41 @@
.buildDeclaration(resolvedAst));
}
- js.Expression generateCode(CodegenWorkItem work, HGraph graph) {
+ js.Expression generateCode(
+ CodegenWorkItem work, HGraph graph, ClosedWorld closedWorld) {
if (work.element.isField) {
- return generateLazyInitializer(work, graph);
+ return generateLazyInitializer(work, graph, closedWorld);
} else {
- return generateMethod(work, graph);
+ return generateMethod(work, graph, closedWorld);
}
}
- js.Expression generateLazyInitializer(CodegenWorkItem work, HGraph graph) {
+ js.Expression generateLazyInitializer(
+ CodegenWorkItem work, HGraph graph, ClosedWorld closedWorld) {
return measure(() {
- compiler.tracer.traceGraph("codegen", graph);
+ backend.tracer.traceGraph("codegen", graph);
SourceInformation sourceInformation = sourceInformationFactory
.createBuilderForContext(work.resolvedAst)
.buildDeclaration(work.resolvedAst);
- SsaCodeGenerator codegen = new SsaCodeGenerator(backend, work);
+ SsaCodeGenerator codegen =
+ new SsaCodeGenerator(backend, closedWorld, work);
codegen.visitGraph(graph);
return new js.Fun(codegen.parameters, codegen.body)
.withSourceInformation(sourceInformation);
});
}
- js.Expression generateMethod(CodegenWorkItem work, HGraph graph) {
+ js.Expression generateMethod(
+ CodegenWorkItem work, HGraph graph, ClosedWorld closedWorld) {
return measure(() {
FunctionElement element = work.element;
if (element.asyncMarker != AsyncMarker.SYNC) {
work.registry.registerAsyncMarker(element);
}
- SsaCodeGenerator codegen = new SsaCodeGenerator(backend, work);
+ SsaCodeGenerator codegen =
+ new SsaCodeGenerator(backend, closedWorld, work);
codegen.visitGraph(graph);
- compiler.tracer.traceGraph("codegen", graph);
+ backend.tracer.traceGraph("codegen", graph);
return buildJavaScriptFunction(
work.resolvedAst, codegen.parameters, codegen.body);
});
@@ -121,6 +126,7 @@
bool isGeneratingExpression = false;
final JavaScriptBackend backend;
+ final ClosedWorld closedWorld;
final CodegenWorkItem work;
final Set<HInstruction> generateAtUseSite;
@@ -163,7 +169,7 @@
// if branches.
SubGraph subGraph;
- SsaCodeGenerator(this.backend, CodegenWorkItem work,
+ SsaCodeGenerator(this.backend, this.closedWorld, CodegenWorkItem work,
{SourceInformation sourceInformation})
: this.work = work,
declaredLocals = new Set<String>(),
@@ -179,8 +185,6 @@
Compiler get compiler => backend.compiler;
- ClosedWorld get closedWorld => compiler.closedWorld;
-
NativeEmitter get nativeEmitter => backend.emitter.nativeEmitter;
CodegenRegistry get registry => work.registry;
@@ -830,7 +834,7 @@
js.Loop loop;
switch (info.kind) {
- // Treate all three "test-first" loops the same way.
+ // Treat all three "test-first" loops the same way.
case HLoopBlockInformation.FOR_LOOP:
case HLoopBlockInformation.WHILE_LOOP:
case HLoopBlockInformation.FOR_IN_LOOP:
diff --git a/pkg/compiler/lib/src/ssa/codegen_helpers.dart b/pkg/compiler/lib/src/ssa/codegen_helpers.dart
index 6058b66..75109a9 100644
--- a/pkg/compiler/lib/src/ssa/codegen_helpers.dart
+++ b/pkg/compiler/lib/src/ssa/codegen_helpers.dart
@@ -147,7 +147,7 @@
ConstantValue constant = new SyntheticConstantValue(
SyntheticConstantKind.DUMMY_INTERCEPTOR,
receiverArgument.instructionType);
- HConstant dummy = graph.addConstant(constant, compiler);
+ HConstant dummy = graph.addConstant(constant, closedWorld);
receiverArgument.usedBy.remove(node);
node.inputs[1] = dummy;
dummy.usedBy.add(node);
diff --git a/pkg/compiler/lib/src/ssa/graph_builder.dart b/pkg/compiler/lib/src/ssa/graph_builder.dart
index ed7683a..35566b8 100644
--- a/pkg/compiler/lib/src/ssa/graph_builder.dart
+++ b/pkg/compiler/lib/src/ssa/graph_builder.dart
@@ -6,6 +6,7 @@
import '../common.dart';
import '../common/codegen.dart' show CodegenRegistry;
import '../compiler.dart';
+import '../constants/constant_system.dart';
import '../dart_types.dart';
import '../elements/elements.dart';
import '../io/source_information.dart';
@@ -42,7 +43,7 @@
CodegenRegistry get registry;
- ClosedWorld get closedWorld => compiler.closedWorld;
+ ClosedWorld get closedWorld;
CommonMasks get commonMasks => closedWorld.commonMasks;
@@ -82,7 +83,7 @@
/// Pushes a boolean checking [expression] against null.
pushCheckNull(HInstruction expression) {
- push(new HIdentity(expression, graph.addConstantNull(compiler), null,
+ push(new HIdentity(expression, graph.addConstantNull(closedWorld), null,
closedWorld.commonMasks.boolType));
}
@@ -292,7 +293,8 @@
List<String> names = type.namedParameters;
for (int index = 0; index < names.length; index++) {
ast.DartString dartString = new ast.DartString.literal(names[index]);
- inputs.add(builder.graph.addConstantString(dartString, builder.compiler));
+ inputs.add(
+ builder.graph.addConstantString(dartString, builder.closedWorld));
namedParameterTypes[index].accept(this, builder);
inputs.add(builder.pop());
}
diff --git a/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart b/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart
index 17de116..2d6a1a7 100644
--- a/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart
+++ b/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart
@@ -37,19 +37,19 @@
class SsaSimplifyInterceptors extends HBaseVisitor
implements OptimizationPhase {
final String name = "SsaSimplifyInterceptors";
- final ConstantSystem constantSystem;
+ final ClosedWorld closedWorld;
final Compiler compiler;
final Element element;
HGraph graph;
- SsaSimplifyInterceptors(this.compiler, this.constantSystem, this.element);
+ SsaSimplifyInterceptors(this.compiler, this.closedWorld, this.element);
JavaScriptBackend get backend => compiler.backend;
- ClosedWorld get closedWorld => compiler.closedWorld;
-
BackendClasses get backendClasses => closedWorld.backendClasses;
+ ConstantSystem get constantSystem => closedWorld.constantSystem;
+
void visitGraph(HGraph graph) {
this.graph = graph;
visitDominatorTree(graph);
@@ -136,7 +136,7 @@
ConstantValue constant =
new InterceptorConstantValue(constantInterceptor.thisType);
- return graph.addConstant(constant, compiler);
+ return graph.addConstant(constant, closedWorld);
}
ClassElement tryComputeConstantInterceptorFromType(
@@ -320,7 +320,7 @@
if (interceptorClass != null) {
HInstruction constantInstruction = graph.addConstant(
new InterceptorConstantValue(interceptorClass.thisType),
- compiler);
+ closedWorld);
node.conditionalConstantInterceptor = constantInstruction;
constantInstruction.usedBy.add(node);
return false;
@@ -360,7 +360,7 @@
} else if (user is HInvokeDynamic) {
if (node == user.inputs[0]) {
// Replace the user with a [HOneShotInterceptor].
- HConstant nullConstant = graph.addConstantNull(compiler);
+ HConstant nullConstant = graph.addConstantNull(closedWorld);
List<HInstruction> inputs = new List<HInstruction>.from(user.inputs);
inputs[0] = nullConstant;
HOneShotInterceptor oneShotInterceptor = new HOneShotInterceptor(
diff --git a/pkg/compiler/lib/src/ssa/jump_handler.dart b/pkg/compiler/lib/src/ssa/jump_handler.dart
index a50d496..d401ca8 100644
--- a/pkg/compiler/lib/src/ssa/jump_handler.dart
+++ b/pkg/compiler/lib/src/ssa/jump_handler.dart
@@ -12,12 +12,12 @@
import 'nodes.dart';
/// A single break/continue instruction.
-class JumpHandlerEntry {
+class _JumpHandlerEntry {
final HJump jumpInstruction;
final LocalsHandler locals;
bool isBreak() => jumpInstruction is HBreak;
bool isContinue() => jumpInstruction is HContinue;
- JumpHandlerEntry(this.jumpInstruction, this.locals);
+ _JumpHandlerEntry(this.jumpInstruction, this.locals);
}
abstract class JumpHandler {
@@ -33,7 +33,7 @@
bool hasAnyBreak();
void close();
final JumpTarget target;
- List<LabelDefinition> labels();
+ List<LabelDefinition> get labels;
}
/// Jump handler used to avoid null checks when a target isn't used as the
@@ -60,7 +60,7 @@
bool hasAnyContinue() => false;
bool hasAnyBreak() => false;
- List<LabelDefinition> labels() => const <LabelDefinition>[];
+ List<LabelDefinition> get labels => const <LabelDefinition>[];
JumpTarget get target => null;
}
@@ -71,11 +71,11 @@
class TargetJumpHandler implements JumpHandler {
final GraphBuilder builder;
final JumpTarget target;
- final List<JumpHandlerEntry> jumps;
+ final List<_JumpHandlerEntry> jumps;
TargetJumpHandler(GraphBuilder builder, this.target)
: this.builder = builder,
- jumps = <JumpHandlerEntry>[] {
+ jumps = <_JumpHandlerEntry>[] {
assert(builder.jumpTargets[target] == null);
builder.jumpTargets[target] = this;
}
@@ -89,7 +89,7 @@
}
LocalsHandler locals = new LocalsHandler.from(builder.localsHandler);
builder.close(breakInstruction);
- jumps.add(new JumpHandlerEntry(breakInstruction, locals));
+ jumps.add(new _JumpHandlerEntry(breakInstruction, locals));
}
void generateContinue([LabelDefinition label]) {
@@ -104,30 +104,30 @@
}
LocalsHandler locals = new LocalsHandler.from(builder.localsHandler);
builder.close(continueInstruction);
- jumps.add(new JumpHandlerEntry(continueInstruction, locals));
+ jumps.add(new _JumpHandlerEntry(continueInstruction, locals));
}
void forEachBreak(Function action) {
- for (JumpHandlerEntry entry in jumps) {
+ for (_JumpHandlerEntry entry in jumps) {
if (entry.isBreak()) action(entry.jumpInstruction, entry.locals);
}
}
void forEachContinue(Function action) {
- for (JumpHandlerEntry entry in jumps) {
+ for (_JumpHandlerEntry entry in jumps) {
if (entry.isContinue()) action(entry.jumpInstruction, entry.locals);
}
}
bool hasAnyContinue() {
- for (JumpHandlerEntry entry in jumps) {
+ for (_JumpHandlerEntry entry in jumps) {
if (entry.isContinue()) return true;
}
return false;
}
bool hasAnyBreak() {
- for (JumpHandlerEntry entry in jumps) {
+ for (_JumpHandlerEntry entry in jumps) {
if (entry.isBreak()) return true;
}
return false;
@@ -138,13 +138,13 @@
builder.jumpTargets.remove(target);
}
- List<LabelDefinition> labels() {
+ List<LabelDefinition> get labels {
List<LabelDefinition> result = null;
for (LabelDefinition element in target.labels) {
- if (result == null) result = <LabelDefinition>[];
+ result ??= <LabelDefinition>[];
result.add(element);
}
- return (result == null) ? const <LabelDefinition>[] : result;
+ return result ?? const <LabelDefinition>[];
}
}
@@ -191,7 +191,7 @@
new HBreak(target, breakSwitchContinueLoop: true);
LocalsHandler locals = new LocalsHandler.from(builder.localsHandler);
builder.close(breakInstruction);
- jumps.add(new JumpHandlerEntry(breakInstruction, locals));
+ jumps.add(new _JumpHandlerEntry(breakInstruction, locals));
} else {
super.generateBreak(label);
}
@@ -211,14 +211,14 @@
// TODO(het): change the graph 'addConstantXXX' to take a ConstantSystem
// instead of a Compiler.
HInstruction value = builder.graph
- .addConstantInt(targetIndexMap[label.target], builder.compiler);
+ .addConstantInt(targetIndexMap[label.target], builder.closedWorld);
builder.localsHandler.updateLocal(target, value);
assert(label.target.labels.contains(label));
HInstruction continueInstruction = new HContinue(target);
LocalsHandler locals = new LocalsHandler.from(builder.localsHandler);
builder.close(continueInstruction);
- jumps.add(new JumpHandlerEntry(continueInstruction, locals));
+ jumps.add(new _JumpHandlerEntry(continueInstruction, locals));
} else {
super.generateContinue(label);
}
diff --git a/pkg/compiler/lib/src/ssa/kernel_ast_adapter.dart b/pkg/compiler/lib/src/ssa/kernel_ast_adapter.dart
index ab92877..00e92f8 100644
--- a/pkg/compiler/lib/src/ssa/kernel_ast_adapter.dart
+++ b/pkg/compiler/lib/src/ssa/kernel_ast_adapter.dart
@@ -5,13 +5,14 @@
import 'package:js_runtime/shared/embedded_names.dart';
import 'package:kernel/ast.dart' as ir;
-import '../constants/expressions.dart';
import '../common.dart';
import '../common/names.dart';
import '../compiler.dart';
+import '../constants/expressions.dart';
import '../constants/values.dart';
import '../dart_types.dart';
import '../elements/elements.dart';
+import '../elements/modelx.dart';
import '../js/js.dart' as js;
import '../js_backend/backend_helpers.dart';
import '../js_backend/js_backend.dart';
@@ -40,6 +41,8 @@
final Map<ir.Node, Element> _nodeToElement;
final Map<ir.VariableDeclaration, SyntheticLocal> _syntheticLocals =
<ir.VariableDeclaration, SyntheticLocal>{};
+ final Map<ir.LabeledStatement, KernelJumpTarget> _jumpTargets =
+ <ir.LabeledStatement, KernelJumpTarget>{};
DartTypeConverter _typeConverter;
KernelAstAdapter(this.kernel, this._backend, this._resolvedAst,
@@ -67,7 +70,6 @@
TreeElements get elements => _resolvedAst.elements;
DiagnosticReporter get reporter => _compiler.reporter;
Element get _target => _resolvedAst.element;
- ClosedWorld get _closedWorld => _compiler.closedWorld;
GlobalTypeInferenceResults get _globalInferenceResults =>
_compiler.globalInference.results;
@@ -129,9 +131,9 @@
return getElement(variable) as LocalElement;
}
- bool getCanThrow(ir.Node procedure) {
+ bool getCanThrow(ir.Node procedure, ClosedWorld closedWorld) {
FunctionElement function = getElement(procedure);
- return !_closedWorld.getCannotThrow(function);
+ return !closedWorld.getCannotThrow(function);
}
TypeMask returnTypeOf(ir.Member node) {
@@ -139,8 +141,8 @@
getElement(node), _globalInferenceResults);
}
- SideEffects getSideEffects(ir.Node node) {
- return _closedWorld.getSideEffectsOfElement(getElement(node));
+ SideEffects getSideEffects(ir.Node node, ClosedWorld closedWorld) {
+ return closedWorld.getSideEffectsOfElement(getElement(node));
}
CallStructure getCallStructure(ir.Arguments arguments) {
@@ -202,13 +204,13 @@
return new Selector.setter(name);
}
- TypeMask typeOfInvocation(ir.MethodInvocation send) {
+ TypeMask typeOfInvocation(ir.MethodInvocation send, ClosedWorld closedWorld) {
ast.Node operatorNode = kernel.nodeToAstOperator[send];
if (operatorNode != null) {
return _resultOf(_target).typeOfOperator(operatorNode);
}
if (send.name.name == '[]=') {
- return _compiler.closedWorld.commonMasks.dynamicType;
+ return closedWorld.commonMasks.dynamicType;
}
return _resultOf(_target).typeOfSend(getNode(send));
}
@@ -217,8 +219,8 @@
return _resultOf(_target).typeOfSend(getNode(getter));
}
- TypeMask typeOfSet(ir.PropertySet setter) {
- return _closedWorld.commonMasks.dynamicType;
+ TypeMask typeOfSet(ir.PropertySet setter, ClosedWorld closedWorld) {
+ return closedWorld.commonMasks.dynamicType;
}
TypeMask typeOfSend(ir.Expression send) {
@@ -226,14 +228,15 @@
return _resultOf(_target).typeOfSend(getNode(send));
}
- TypeMask typeOfListLiteral(Element owner, ir.ListLiteral listLiteral) {
+ TypeMask typeOfListLiteral(
+ Element owner, ir.ListLiteral listLiteral, ClosedWorld closedWorld) {
ast.Node node = getNodeOrNull(listLiteral);
if (node == null) {
assertNodeIsSynthetic(listLiteral);
- return _closedWorld.commonMasks.growableListType;
+ return closedWorld.commonMasks.growableListType;
}
return _resultOf(owner).typeOfNewList(getNode(listLiteral)) ??
- _closedWorld.commonMasks.dynamicType;
+ closedWorld.commonMasks.dynamicType;
}
TypeMask typeOfIterator(ir.ForInStatement forInStatement) {
@@ -248,27 +251,25 @@
return _resultOf(_target).typeOfIteratorMoveNext(getNode(forInStatement));
}
- bool isJsIndexableIterator(ir.ForInStatement forInStatement) {
+ bool isJsIndexableIterator(
+ ir.ForInStatement forInStatement, ClosedWorld closedWorld) {
TypeMask mask = typeOfIterator(forInStatement);
return mask != null &&
- mask.satisfies(_backend.helpers.jsIndexableClass, _closedWorld) &&
+ mask.satisfies(_backend.helpers.jsIndexableClass, closedWorld) &&
// String is indexable but not iterable.
- !mask.satisfies(_backend.helpers.jsStringClass, _closedWorld);
+ !mask.satisfies(_backend.helpers.jsStringClass, closedWorld);
}
- bool isFixedLength(TypeMask mask) {
- JavaScriptBackend backend = _compiler.backend;
+ bool isFixedLength(TypeMask mask, ClosedWorld closedWorld) {
if (mask.isContainer && (mask as ContainerTypeMask).length != null) {
// A container on which we have inferred the length.
return true;
}
// TODO(sra): Recognize any combination of fixed length indexables.
- if (mask.containsOnly(
- _closedWorld.backendClasses.fixedListImplementation) ||
- mask.containsOnly(
- _closedWorld.backendClasses.constListImplementation) ||
- mask.containsOnlyString(_closedWorld) ||
- _closedWorld.commonMasks.isTypedArray(mask)) {
+ if (mask.containsOnly(closedWorld.backendClasses.fixedListImplementation) ||
+ mask.containsOnly(closedWorld.backendClasses.constListImplementation) ||
+ mask.containsOnlyString(closedWorld) ||
+ closedWorld.commonMasks.isTypedArray(mask)) {
return true;
}
return false;
@@ -289,8 +290,9 @@
selector, mask, _globalInferenceResults);
}
- TypeMask typeFromNativeBehavior(native.NativeBehavior nativeBehavior) {
- return TypeMaskFactory.fromNativeBehavior(nativeBehavior, _closedWorld);
+ TypeMask typeFromNativeBehavior(
+ native.NativeBehavior nativeBehavior, ClosedWorld closedWorld) {
+ return TypeMaskFactory.fromNativeBehavior(nativeBehavior, closedWorld);
}
ConstantValue getConstantFor(ir.Node node) {
@@ -342,6 +344,16 @@
JumpTarget getTargetDefinition(ir.Node node) =>
elements.getTargetDefinition(getNode(node));
+ JumpTarget getTargetOf(ir.Node node) => elements.getTargetOf(getNode(node));
+
+ KernelJumpTarget getJumpTarget(ir.LabeledStatement labeledStatement) =>
+ _jumpTargets.putIfAbsent(labeledStatement, () {
+ return new KernelJumpTarget();
+ });
+
+ LabelDefinition getTargetLabel(ir.Node node) =>
+ elements.getTargetLabel(getNode(node));
+
ir.Class get mapLiteralClass =>
kernel.classes[_backend.helpers.mapLiteralClass];
@@ -761,9 +773,14 @@
} else if (node.parameter.parent is ir.FunctionNode) {
ir.FunctionNode func = node.parameter.parent;
int index = func.typeParameters.indexOf(node.parameter);
- ConstructorElement constructorElement = astAdapter.getElement(func);
- ClassElement classElement = constructorElement.enclosingClass;
- return classElement.typeVariables[index];
+ Element element = astAdapter.getElement(func);
+ if (element.isConstructor) {
+ ClassElement classElement = element.enclosingClass;
+ return classElement.typeVariables[index];
+ } else {
+ GenericElement genericElement = element;
+ return genericElement.typeVariables[index];
+ }
}
throw new UnsupportedError('Unsupported type parameter type node $node.');
}
@@ -875,3 +892,55 @@
return new StringConstantExpression(node.value);
}
}
+
+class KernelJumpTarget extends JumpTarget {
+ static int index = 0;
+
+ KernelJumpTarget() {
+ labels = <LabelDefinition>[
+ new LabelDefinitionX(null, 'l${index++}', this)..setBreakTarget()
+ ];
+ }
+
+ @override
+ bool get isBreakTarget => true;
+
+ set isBreakTarget(bool x) {
+ // do nothing, these are always break targets
+ }
+
+ @override
+ bool get isContinueTarget => false;
+
+ set isContinueTarget(bool x) {
+ // do nothing, these are always break targets
+ }
+
+ @override
+ LabelDefinition addLabel(ast.Label label, String labelName) {
+ LabelDefinition result = new LabelDefinitionX(label, labelName, this);
+ labels.add(result);
+ return result;
+ }
+
+ @override
+ ExecutableElement get executableContext => null;
+
+ @override
+ bool get isSwitch => false;
+
+ @override
+ bool get isTarget => true;
+
+ @override
+ List<LabelDefinition> labels;
+
+ @override
+ String get name => null;
+
+ @override
+ int get nestingLevel => 1;
+
+ @override
+ ast.Node get statement => null;
+}
diff --git a/pkg/compiler/lib/src/ssa/locals_handler.dart b/pkg/compiler/lib/src/ssa/locals_handler.dart
index 1d9fdde..79d7372 100644
--- a/pkg/compiler/lib/src/ssa/locals_handler.dart
+++ b/pkg/compiler/lib/src/ssa/locals_handler.dart
@@ -575,7 +575,7 @@
LocalsHandler mergeMultiple(
List<LocalsHandler> localsHandlers, HBasicBlock joinBlock) {
assert(localsHandlers.length > 0);
- if (localsHandlers.length == 1) return localsHandlers[0];
+ if (localsHandlers.length == 1) return localsHandlers.single;
Map<Local, HInstruction> joinedLocals = new Map<Local, HInstruction>();
HInstruction thisValue = null;
directLocals.forEach((Local local, HInstruction instruction) {
diff --git a/pkg/compiler/lib/src/ssa/loop_handler.dart b/pkg/compiler/lib/src/ssa/loop_handler.dart
index e897820..7edcfeb 100644
--- a/pkg/compiler/lib/src/ssa/loop_handler.dart
+++ b/pkg/compiler/lib/src/ssa/loop_handler.dart
@@ -106,12 +106,12 @@
builder.localsHandler =
continueHandlers[0].mergeMultiple(continueHandlers, updateBlock);
- List<LabelDefinition> labels = jumpHandler.labels();
+ List<LabelDefinition> labels = jumpHandler.labels;
JumpTarget target = getTargetDefinition(loop);
- if (!labels.isEmpty) {
+ if (labels.isNotEmpty) {
beginBodyBlock.setBlockFlow(
new HLabeledBlockInformation(
- new HSubGraphBlockInformation(bodyGraph), jumpHandler.labels(),
+ new HSubGraphBlockInformation(bodyGraph), jumpHandler.labels,
isContinue: true),
updateBlock);
} else if (target != null && target.isContinueTarget) {
@@ -222,7 +222,7 @@
JumpHandler jumpHandler = createJumpHandler(node, isLoopJump: true);
HBasicBlock loopEntry = builder.graph
- .addNewLoopHeaderBlock(jumpHandler.target, jumpHandler.labels());
+ .addNewLoopHeaderBlock(jumpHandler.target, jumpHandler.labels);
previousBlock.addSuccessor(loopEntry);
builder.open(loopEntry);
@@ -350,7 +350,7 @@
// TODO(het): Since kernel simplifies loop breaks and continues, we should
// rewrite the loop handler from scratch to account for the simplified structure
-class KernelLoopHandler extends LoopHandler<ir.Node> {
+class KernelLoopHandler extends LoopHandler<ir.TreeNode> {
final KernelSsaBuilder builder;
KernelAstAdapter get astAdapter => builder.astAdapter;
@@ -360,33 +360,35 @@
super(builder);
@override
- JumpHandler createJumpHandler(ir.Node node, {bool isLoopJump}) {
- JumpTarget element = getTargetDefinition(node);
- if (element == null || !identical(element.statement, node)) {
+ JumpHandler createJumpHandler(ir.TreeNode node, {bool isLoopJump}) {
+ if (node.parent is! ir.LabeledStatement) {
// No breaks or continues to this node.
return new NullJumpHandler(builder.compiler.reporter);
}
- if (isLoopJump && node is ast.SwitchStatement) {
- // Create a special jump handler for loops created for switch statements
- // with continue statements.
- return new SwitchCaseJumpHandler(builder, element, getNode(node));
- }
- return new JumpHandler(builder, element);
+ // We must have already created a JumpHandler for the labeled statement
+ JumpHandler result =
+ builder.jumpTargets[astAdapter.getJumpTarget(node.parent)];
+ assert(result != null);
+ return result;
}
@override
- ast.Node getNode(ir.Node node) => astAdapter.getNode(node);
+ ast.Node getNode(ir.TreeNode node) => astAdapter.getNode(node);
@override
- JumpTarget getTargetDefinition(ir.Node node) =>
- astAdapter.getTargetDefinition(node);
+ JumpTarget getTargetDefinition(ir.TreeNode node) {
+ if (node.parent is ir.LabeledStatement) {
+ return astAdapter.getJumpTarget(node.parent);
+ }
+ return null;
+ }
@override
- int loopKind(ir.Node node) => node.accept(new _KernelLoopTypeVisitor());
+ int loopKind(ir.TreeNode node) => node.accept(new _KernelLoopTypeVisitor());
// TODO(het): return the actual source information
@override
- SourceInformation loopSourceInformation(ir.Node node) => null;
+ SourceInformation loopSourceInformation(ir.TreeNode node) => null;
}
class _KernelLoopTypeVisitor extends ir.Visitor<int> {
diff --git a/pkg/compiler/lib/src/ssa/nodes.dart b/pkg/compiler/lib/src/ssa/nodes.dart
index 83ecc44..a711e41 100644
--- a/pkg/compiler/lib/src/ssa/nodes.dart
+++ b/pkg/compiler/lib/src/ssa/nodes.dart
@@ -207,7 +207,7 @@
return result;
}
- HConstant addConstant(ConstantValue constant, Compiler compiler,
+ HConstant addConstant(ConstantValue constant, ClosedWorld closedWorld,
{SourceInformation sourceInformation}) {
HConstant result = constants[constant];
// TODO(johnniwinther): Support source information per constant reference.
@@ -216,7 +216,7 @@
// We use `null` as the value for invalid constant expressions.
constant = const NullConstantValue();
}
- TypeMask type = computeTypeMask(compiler, constant);
+ TypeMask type = computeTypeMask(closedWorld, constant);
result = new HConstant.internal(constant, type)
..sourceInformation = sourceInformation;
entry.addAtExit(result);
@@ -228,43 +228,47 @@
return result;
}
- HConstant addDeferredConstant(ConstantValue constant, Entity prefix,
- SourceInformation sourceInformation, Compiler compiler) {
+ HConstant addDeferredConstant(
+ ConstantValue constant,
+ Entity prefix,
+ SourceInformation sourceInformation,
+ Compiler compiler,
+ ClosedWorld closedWorld) {
// TODO(sigurdm,johnniwinther): These deferred constants should be created
// by the constant evaluator.
ConstantValue wrapper = new DeferredConstantValue(constant, prefix);
compiler.deferredLoadTask.registerConstantDeferredUse(wrapper, prefix);
- return addConstant(wrapper, compiler, sourceInformation: sourceInformation);
+ return addConstant(wrapper, closedWorld,
+ sourceInformation: sourceInformation);
}
- HConstant addConstantInt(int i, Compiler compiler) {
- return addConstant(compiler.backend.constantSystem.createInt(i), compiler);
+ HConstant addConstantInt(int i, ClosedWorld closedWorld) {
+ return addConstant(closedWorld.constantSystem.createInt(i), closedWorld);
}
- HConstant addConstantDouble(double d, Compiler compiler) {
+ HConstant addConstantDouble(double d, ClosedWorld closedWorld) {
+ return addConstant(closedWorld.constantSystem.createDouble(d), closedWorld);
+ }
+
+ HConstant addConstantString(ast.DartString str, ClosedWorld closedWorld) {
return addConstant(
- compiler.backend.constantSystem.createDouble(d), compiler);
+ closedWorld.constantSystem.createString(str), closedWorld);
}
- HConstant addConstantString(ast.DartString str, Compiler compiler) {
- return addConstant(
- compiler.backend.constantSystem.createString(str), compiler);
- }
-
- HConstant addConstantStringFromName(js.Name name, Compiler compiler) {
+ HConstant addConstantStringFromName(js.Name name, ClosedWorld closedWorld) {
return addConstant(
new SyntheticConstantValue(
SyntheticConstantKind.NAME, js.quoteName(name)),
- compiler);
+ closedWorld);
}
- HConstant addConstantBool(bool value, Compiler compiler) {
+ HConstant addConstantBool(bool value, ClosedWorld closedWorld) {
return addConstant(
- compiler.backend.constantSystem.createBool(value), compiler);
+ closedWorld.constantSystem.createBool(value), closedWorld);
}
- HConstant addConstantNull(Compiler compiler) {
- return addConstant(compiler.backend.constantSystem.createNull(), compiler);
+ HConstant addConstantNull(ClosedWorld closedWorld) {
+ return addConstant(closedWorld.constantSystem.createNull(), closedWorld);
}
void finalize() {
@@ -2161,11 +2165,9 @@
}
class HBreak extends HJump {
- /**
- * Signals that this is a special break instruction for the synthetic loop
- * generatedfor a switch statement with continue statements. See
- * [SsaFromAstMixin.buildComplexSwitchStatement] for detail.
- */
+ /// Signals that this is a special break instruction for the synthetic loop
+ /// generated for a switch statement with continue statements. See
+ /// [SsaFromAstMixin.buildComplexSwitchStatement] for detail.
final bool breakSwitchContinueLoop;
HBreak(JumpTarget target, {bool this.breakSwitchContinueLoop: false})
: super(target);
diff --git a/pkg/compiler/lib/src/ssa/optimize.dart b/pkg/compiler/lib/src/ssa/optimize.dart
index 0703f1c..2c6cdb8 100644
--- a/pkg/compiler/lib/src/ssa/optimize.dart
+++ b/pkg/compiler/lib/src/ssa/optimize.dart
@@ -8,7 +8,7 @@
import '../compiler.dart' show Compiler;
import '../constants/constant_system.dart';
import '../constants/values.dart';
-import '../core_types.dart' show CommonElements, CoreClasses;
+import '../core_types.dart' show CommonElements;
import '../dart_types.dart';
import '../elements/elements.dart';
import '../js/js.dart' as js;
@@ -35,22 +35,24 @@
class SsaOptimizerTask extends CompilerTask {
final JavaScriptBackend backend;
+
+ Map<HInstruction, Range> ranges = <HInstruction, Range>{};
+
SsaOptimizerTask(JavaScriptBackend backend)
: this.backend = backend,
super(backend.compiler.measurer);
- String get name => 'SSA optimizer';
- Compiler get compiler => backend.compiler;
- ClosedWorld get closedWorld => compiler.closedWorld;
- Map<HInstruction, Range> ranges = <HInstruction, Range>{};
- void optimize(CodegenWorkItem work, HGraph graph) {
+ String get name => 'SSA optimizer';
+
+ Compiler get compiler => backend.compiler;
+
+ void optimize(CodegenWorkItem work, HGraph graph, ClosedWorld closedWorld) {
void runPhase(OptimizationPhase phase) {
measureSubtask(phase.name, () => phase.visitGraph(graph));
- compiler.tracer.traceGraph(phase.name, graph);
+ backend.tracer.traceGraph(phase.name, graph);
assert(graph.isValid());
}
- ConstantSystem constantSystem = compiler.backend.constantSystem;
bool trustPrimitives = compiler.options.trustPrimitives;
CodegenRegistry registry = work.registry;
Set<HInstruction> boundsChecked = new Set<HInstruction>();
@@ -59,36 +61,36 @@
List<OptimizationPhase> phases = <OptimizationPhase>[
// Run trivial instruction simplification first to optimize
// some patterns useful for type conversion.
- new SsaInstructionSimplifier(constantSystem, backend, this, registry),
+ new SsaInstructionSimplifier(backend, closedWorld, this, registry),
new SsaTypeConversionInserter(closedWorld),
new SsaRedundantPhiEliminator(),
new SsaDeadPhiEliminator(),
- new SsaTypePropagator(compiler),
+ new SsaTypePropagator(compiler, closedWorld),
// After type propagation, more instructions can be
// simplified.
- new SsaInstructionSimplifier(constantSystem, backend, this, registry),
+ new SsaInstructionSimplifier(backend, closedWorld, this, registry),
new SsaCheckInserter(
trustPrimitives, backend, closedWorld, boundsChecked),
- new SsaInstructionSimplifier(constantSystem, backend, this, registry),
+ new SsaInstructionSimplifier(backend, closedWorld, this, registry),
new SsaCheckInserter(
trustPrimitives, backend, closedWorld, boundsChecked),
- new SsaTypePropagator(compiler),
+ new SsaTypePropagator(compiler, closedWorld),
// Run a dead code eliminator before LICM because dead
// interceptors are often in the way of LICM'able instructions.
- new SsaDeadCodeEliminator(compiler, this),
- new SsaGlobalValueNumberer(compiler),
+ new SsaDeadCodeEliminator(closedWorld, this),
+ new SsaGlobalValueNumberer(),
// After GVN, some instructions might need their type to be
// updated because they now have different inputs.
- new SsaTypePropagator(compiler),
+ new SsaTypePropagator(compiler, closedWorld),
codeMotion = new SsaCodeMotion(),
- new SsaLoadElimination(compiler),
+ new SsaLoadElimination(compiler, closedWorld),
new SsaRedundantPhiEliminator(),
new SsaDeadPhiEliminator(),
- new SsaTypePropagator(compiler),
- new SsaValueRangeAnalyzer(compiler, constantSystem, this),
+ new SsaTypePropagator(compiler, closedWorld),
+ new SsaValueRangeAnalyzer(backend.helpers, closedWorld, this),
// Previous optimizations may have generated new
// opportunities for instruction simplification.
- new SsaInstructionSimplifier(constantSystem, backend, this, registry),
+ new SsaInstructionSimplifier(backend, closedWorld, this, registry),
new SsaCheckInserter(
trustPrimitives, backend, closedWorld, boundsChecked),
];
@@ -98,28 +100,28 @@
// required for implementation correctness because the code generator
// assumes it is always performed.
runPhase(
- new SsaSimplifyInterceptors(compiler, constantSystem, work.element));
+ new SsaSimplifyInterceptors(compiler, closedWorld, work.element));
- SsaDeadCodeEliminator dce = new SsaDeadCodeEliminator(compiler, this);
+ SsaDeadCodeEliminator dce = new SsaDeadCodeEliminator(closedWorld, this);
runPhase(dce);
if (codeMotion.movedCode || dce.eliminatedSideEffects) {
phases = <OptimizationPhase>[
- new SsaTypePropagator(compiler),
- new SsaGlobalValueNumberer(compiler),
+ new SsaTypePropagator(compiler, closedWorld),
+ new SsaGlobalValueNumberer(),
new SsaCodeMotion(),
- new SsaValueRangeAnalyzer(compiler, constantSystem, this),
- new SsaInstructionSimplifier(constantSystem, backend, this, registry),
+ new SsaValueRangeAnalyzer(backend.helpers, closedWorld, this),
+ new SsaInstructionSimplifier(backend, closedWorld, this, registry),
new SsaCheckInserter(
trustPrimitives, backend, closedWorld, boundsChecked),
- new SsaSimplifyInterceptors(compiler, constantSystem, work.element),
- new SsaDeadCodeEliminator(compiler, this),
+ new SsaSimplifyInterceptors(compiler, closedWorld, work.element),
+ new SsaDeadCodeEliminator(closedWorld, this),
];
} else {
phases = <OptimizationPhase>[
- new SsaTypePropagator(compiler),
+ new SsaTypePropagator(compiler, closedWorld),
// Run the simplifier to remove unneeded type checks inserted by
// type propagation.
- new SsaInstructionSimplifier(constantSystem, backend, this, registry),
+ new SsaInstructionSimplifier(backend, closedWorld, this, registry),
];
}
phases.forEach(runPhase);
@@ -131,9 +133,7 @@
/// cannot change. The current implementation is conservative for the purpose
/// of identifying gvn-able lengths and mis-identifies some unions of fixed
/// length indexables (see TODO) as not fixed length.
-bool isFixedLength(mask, Compiler compiler) {
- ClosedWorld closedWorld = compiler.closedWorld;
- JavaScriptBackend backend = compiler.backend;
+bool isFixedLength(mask, ClosedWorld closedWorld) {
if (mask.isContainer && mask.length != null) {
// A container on which we have inferred the length.
return true;
@@ -161,21 +161,21 @@
final String name = "SsaInstructionSimplifier";
final JavaScriptBackend backend;
- final ConstantSystem constantSystem;
+ final ClosedWorld closedWorld;
final CodegenRegistry registry;
HGraph graph;
Compiler get compiler => backend.compiler;
final SsaOptimizerTask optimizer;
SsaInstructionSimplifier(
- this.constantSystem, this.backend, this.optimizer, this.registry);
-
- ClosedWorld get closedWorld => compiler.closedWorld;
+ this.backend, this.closedWorld, this.optimizer, this.registry);
CommonElements get commonElements => closedWorld.commonElements;
BackendHelpers get helpers => backend.helpers;
+ ConstantSystem get constantSystem => closedWorld.constantSystem;
+
GlobalTypeInferenceResults get globalInferenceResults =>
compiler.globalInference.results;
@@ -249,7 +249,7 @@
if (node.usedBy.isEmpty) return;
ConstantValue value = getConstantFromType(node);
if (value != null) {
- HConstant constant = graph.addConstant(value, compiler);
+ HConstant constant = graph.addConstant(value, closedWorld);
for (HInstruction user in node.usedBy.toList()) {
user.changeUse(node, constant);
}
@@ -296,7 +296,7 @@
// All values that cannot be 'true' are boolified to false.
TypeMask mask = input.instructionType;
if (!mask.contains(helpers.jsBoolClass, closedWorld)) {
- return graph.addConstantBool(false, compiler);
+ return graph.addConstantBool(false, closedWorld);
}
return node;
}
@@ -308,7 +308,7 @@
if (input is HConstant) {
HConstant constant = input;
bool isTrue = constant.constant.isTrue;
- return graph.addConstantBool(!isTrue, compiler);
+ return graph.addConstantBool(!isTrue, closedWorld);
} else if (input is HNot) {
return input.inputs[0];
}
@@ -325,7 +325,7 @@
if (operand is HConstant) {
HConstant receiver = operand;
ConstantValue folded = operation.fold(receiver.constant);
- if (folded != null) return graph.addConstant(folded, compiler);
+ if (folded != null) return graph.addConstant(folded, closedWorld);
}
return null;
}
@@ -336,14 +336,14 @@
if (actualReceiver.isConstantString()) {
HConstant constantInput = actualReceiver;
StringConstantValue constant = constantInput.constant;
- return graph.addConstantInt(constant.length, compiler);
+ return graph.addConstantInt(constant.length, closedWorld);
} else if (actualReceiver.isConstantList()) {
HConstant constantInput = actualReceiver;
ListConstantValue constant = constantInput.constant;
- return graph.addConstantInt(constant.length, compiler);
+ return graph.addConstantInt(constant.length, closedWorld);
}
MemberElement element = helpers.jsIndexableLength;
- bool isFixed = isFixedLength(actualReceiver.instructionType, compiler);
+ bool isFixed = isFixedLength(actualReceiver.instructionType, closedWorld);
TypeMask actualType = node.instructionType;
TypeMask resultType = closedWorld.commonMasks.positiveIntType;
// If we already have computed a more specific type, keep that type.
@@ -360,7 +360,7 @@
} else if (actualReceiver.isConstantMap()) {
HConstant constantInput = actualReceiver;
MapConstantValue constant = constantInput.constant;
- return graph.addConstantInt(constant.length, compiler);
+ return graph.addConstantInt(constant.length, closedWorld);
}
return null;
}
@@ -585,7 +585,7 @@
HConstant op1 = left;
HConstant op2 = right;
ConstantValue folded = operation.fold(op1.constant, op2.constant);
- if (folded != null) return graph.addConstant(folded, compiler);
+ if (folded != null) return graph.addConstant(folded, closedWorld);
}
return null;
}
@@ -646,8 +646,8 @@
TypeMask leftType = left.instructionType;
TypeMask rightType = right.instructionType;
- HInstruction makeTrue() => graph.addConstantBool(true, compiler);
- HInstruction makeFalse() => graph.addConstantBool(false, compiler);
+ HInstruction makeTrue() => graph.addConstantBool(true, closedWorld);
+ HInstruction makeFalse() => graph.addConstantBool(false, closedWorld);
// Intersection of int and double return conflicting, so
// we don't optimize on numbers to preserve the runtime semantics.
@@ -698,7 +698,7 @@
void simplifyCondition(
HBasicBlock block, HInstruction condition, bool value) {
condition.dominatedUsers(block.first).forEach((user) {
- HInstruction newCondition = graph.addConstantBool(value, compiler);
+ HInstruction newCondition = graph.addConstantBool(value, closedWorld);
user.changeUse(condition, newCondition);
});
}
@@ -741,7 +741,7 @@
}
if (type.isObject || type.treatAsDynamic) {
- return graph.addConstantBool(true, compiler);
+ return graph.addConstantBool(true, closedWorld);
}
HInstruction expression = node.expression;
@@ -749,30 +749,30 @@
if (element == commonElements.intClass ||
element == commonElements.numClass ||
Elements.isNumberOrStringSupertype(element, commonElements)) {
- return graph.addConstantBool(true, compiler);
+ return graph.addConstantBool(true, closedWorld);
} else if (element == commonElements.doubleClass) {
// We let the JS semantics decide for that check. Currently
// the code we emit will always return true.
return node;
} else {
- return graph.addConstantBool(false, compiler);
+ return graph.addConstantBool(false, closedWorld);
}
} else if (expression.isDouble(closedWorld)) {
if (element == commonElements.doubleClass ||
element == commonElements.numClass ||
Elements.isNumberOrStringSupertype(element, commonElements)) {
- return graph.addConstantBool(true, compiler);
+ return graph.addConstantBool(true, closedWorld);
} else if (element == commonElements.intClass) {
// We let the JS semantics decide for that check. Currently
// the code we emit will return true for a double that can be
// represented as a 31-bit integer and for -0.0.
return node;
} else {
- return graph.addConstantBool(false, compiler);
+ return graph.addConstantBool(false, closedWorld);
}
} else if (expression.isNumber(closedWorld)) {
if (element == commonElements.numClass) {
- return graph.addConstantBool(true, compiler);
+ return graph.addConstantBool(true, closedWorld);
} else {
// We cannot just return false, because the expression may be of
// type int or double.
@@ -792,9 +792,9 @@
? new TypeMask.subtype(element, closedWorld)
: new TypeMask.nonNullSubtype(element, closedWorld);
if (expressionMask.union(typeMask, closedWorld) == typeMask) {
- return graph.addConstantBool(true, compiler);
+ return graph.addConstantBool(true, closedWorld);
} else if (expressionMask.isDisjoint(typeMask, closedWorld)) {
- return graph.addConstantBool(false, compiler);
+ return graph.addConstantBool(false, closedWorld);
}
}
return node;
@@ -865,11 +865,12 @@
return receiver.inputs[0];
}
} else if (receiver.isConstantList() || receiver.isConstantString()) {
- return graph.addConstantInt(receiver.constant.length, compiler);
+ return graph.addConstantInt(receiver.constant.length, closedWorld);
} else {
var type = receiver.instructionType;
if (type.isContainer && type.length != null) {
- HInstruction constant = graph.addConstantInt(type.length, compiler);
+ HInstruction constant =
+ graph.addConstantInt(type.length, closedWorld);
if (type.isNullable) {
// If the container can be null, we update all uses of the
// length access to use the constant instead, but keep the
@@ -893,7 +894,7 @@
Map<Element, ConstantValue> fields = constructedConstant.fields;
ConstantValue value = fields[node.element];
if (value != null) {
- return graph.addConstant(value, compiler);
+ return graph.addConstant(value, closedWorld);
}
}
}
@@ -908,7 +909,7 @@
instruction = node.index;
int index = instruction.constant.primitiveValue;
if (index >= 0 && index < entries.length) {
- return graph.addConstant(entries[index], compiler);
+ return graph.addConstant(entries[index], closedWorld);
}
}
return node;
@@ -1063,7 +1064,7 @@
HInstruction folded = graph.addConstant(
constantSystem.createString(new ast.DartString.concat(
leftString.primitiveValue, rightString.primitiveValue)),
- compiler);
+ closedWorld);
if (prefix == null) return folded;
return new HStringConcat(
prefix, folded, closedWorld.commonMasks.stringType);
@@ -1087,7 +1088,7 @@
}
PrimitiveConstantValue primitive = constant.constant;
return graph.addConstant(
- constantSystem.createString(primitive.toDartString()), compiler);
+ constantSystem.createString(primitive.toDartString()), closedWorld);
}
HInstruction tryToString() {
@@ -1280,7 +1281,7 @@
return finishSubstituted(
object.element,
// If there are type arguments, all type arguments are 'dynamic'.
- (int i) => graph.addConstantNull(compiler));
+ (int i) => graph.addConstantNull(closedWorld));
}
}
@@ -1327,10 +1328,9 @@
HBoundsCheck insertBoundsCheck(
HInstruction indexNode, HInstruction array, HInstruction indexArgument) {
- Compiler compiler = backend.compiler;
HFieldGet length = new HFieldGet(helpers.jsIndexableLength, array,
closedWorld.commonMasks.positiveIntType,
- isAssignable: !isFixedLength(array.instructionType, compiler));
+ isAssignable: !isFixedLength(array.instructionType, closedWorld));
indexNode.block.addBefore(indexNode, length);
TypeMask type = indexArgument.isPositiveInteger(closedWorld)
@@ -1372,8 +1372,8 @@
// `0` is the index we want to check, but we want to report `-1`, as if we
// executed `a[a.length-1]`
HBoundsCheck check = insertBoundsCheck(
- node, node.receiver, graph.addConstantInt(0, backend.compiler));
- HInstruction minusOne = graph.addConstantInt(-1, backend.compiler);
+ node, node.receiver, graph.addConstantInt(0, closedWorld));
+ HInstruction minusOne = graph.addConstantInt(-1, closedWorld);
check.inputs.add(minusOne);
minusOne.usedBy.add(check);
}
@@ -1382,16 +1382,14 @@
class SsaDeadCodeEliminator extends HGraphVisitor implements OptimizationPhase {
final String name = "SsaDeadCodeEliminator";
- final Compiler compiler;
+ final ClosedWorld closedWorld;
final SsaOptimizerTask optimizer;
SsaLiveBlockAnalyzer analyzer;
Map<HInstruction, bool> trivialDeadStoreReceivers =
new Maplet<HInstruction, bool>();
bool eliminatedSideEffects = false;
- SsaDeadCodeEliminator(this.compiler, this.optimizer);
-
- ClosedWorld get closedWorld => compiler.closedWorld;
+ SsaDeadCodeEliminator(this.closedWorld, this.optimizer);
HInstruction zapInstructionCache;
HInstruction get zapInstruction {
@@ -1399,7 +1397,7 @@
// A constant with no type does not pollute types at phi nodes.
ConstantValue constant = new SyntheticConstantValue(
SyntheticConstantKind.EMPTY_VALUE, const TypeMask.nonNullEmpty());
- zapInstructionCache = analyzer.graph.addConstant(constant, compiler);
+ zapInstructionCache = analyzer.graph.addConstant(constant, closedWorld);
}
return zapInstructionCache;
}
@@ -1794,13 +1792,12 @@
class SsaGlobalValueNumberer implements OptimizationPhase {
final String name = "SsaGlobalValueNumberer";
- final Compiler compiler;
final Set<int> visited;
List<int> blockChangesFlags;
List<int> loopChangesFlags;
- SsaGlobalValueNumberer(this.compiler) : visited = new Set<int>();
+ SsaGlobalValueNumberer() : visited = new Set<int>();
void visitGraph(HGraph graph) {
computeChangesFlags(graph);
@@ -2228,13 +2225,12 @@
*/
class SsaLoadElimination extends HBaseVisitor implements OptimizationPhase {
final Compiler compiler;
+ final ClosedWorld closedWorld;
final String name = "SsaLoadElimination";
MemorySet memorySet;
List<MemorySet> memories;
- SsaLoadElimination(this.compiler);
-
- ClosedWorld get closedWorld => compiler.closedWorld;
+ SsaLoadElimination(this.compiler, this.closedWorld);
void visitGraph(HGraph graph) {
memories = new List<MemorySet>(graph.blocks.length);
diff --git a/pkg/compiler/lib/src/ssa/ssa.dart b/pkg/compiler/lib/src/ssa/ssa.dart
index 55b13b0..92f05f9 100644
--- a/pkg/compiler/lib/src/ssa/ssa.dart
+++ b/pkg/compiler/lib/src/ssa/ssa.dart
@@ -10,6 +10,7 @@
import '../io/source_information.dart';
import '../js/js.dart' as js;
import '../js_backend/backend.dart' show JavaScriptBackend, FunctionCompiler;
+import '../world.dart' show ClosedWorld;
import 'builder.dart';
import 'builder_kernel.dart';
@@ -36,11 +37,13 @@
/// Generates JavaScript code for `work.element`.
/// Using the ssa builder, optimizer and codegenerator.
- js.Fun compile(CodegenWorkItem work) {
- HGraph graph = useKernel ? builderKernel.build(work) : builder.build(work);
- optimizer.optimize(work, graph);
+ js.Fun compile(CodegenWorkItem work, ClosedWorld closedWorld) {
+ HGraph graph = useKernel
+ ? builderKernel.build(work, closedWorld)
+ : builder.build(work, closedWorld);
+ optimizer.optimize(work, graph, closedWorld);
Element element = work.element;
- js.Expression result = generator.generateCode(work, graph);
+ js.Expression result = generator.generateCode(work, graph, closedWorld);
if (element is FunctionElement) {
// TODO(sigmund): replace by kernel transformer when `useKernel` is true.
result = backend.rewriteAsync(element, result);
diff --git a/pkg/compiler/lib/src/ssa/ssa_branch_builder.dart b/pkg/compiler/lib/src/ssa/ssa_branch_builder.dart
index b34552c..8c1fa21 100644
--- a/pkg/compiler/lib/src/ssa/ssa_branch_builder.dart
+++ b/pkg/compiler/lib/src/ssa/ssa_branch_builder.dart
@@ -171,7 +171,8 @@
}
handleIf(visitCondition, visitThen, null);
- HConstant notIsAnd = builder.graph.addConstantBool(!isAnd, compiler);
+ HConstant notIsAnd =
+ builder.graph.addConstantBool(!isAnd, builder.closedWorld);
HPhi result = new HPhi.manyInputs(
null,
<HInstruction>[boolifiedRight, notIsAnd],
diff --git a/pkg/compiler/lib/src/ssa/ssa_tracer.dart b/pkg/compiler/lib/src/ssa/ssa_tracer.dart
index ce13448..df84e84 100644
--- a/pkg/compiler/lib/src/ssa/ssa_tracer.dart
+++ b/pkg/compiler/lib/src/ssa/ssa_tracer.dart
@@ -6,9 +6,8 @@
import 'dart:async' show EventSink;
-import '../compiler.dart' show Compiler;
import '../diagnostics/invariant.dart' show DEBUG_MODE;
-import '../js_backend/js_backend.dart';
+import '../js_backend/namer.dart' show Namer;
import '../tracer.dart';
import '../world.dart' show ClosedWorld;
import 'nodes.dart';
@@ -19,10 +18,11 @@
* to enable it.
*/
class HTracer extends HGraphVisitor with TracerUtil {
- Compiler compiler;
+ final ClosedWorld closedWorld;
+ final Namer namer;
final EventSink<String> output;
- HTracer(this.output, this.compiler);
+ HTracer(this.output, this.closedWorld, this.namer);
void traceGraph(String name, HGraph graph) {
DEBUG_MODE = true;
@@ -76,7 +76,7 @@
void visitBasicBlock(HBasicBlock block) {
HInstructionStringifier stringifier =
- new HInstructionStringifier(block, compiler);
+ new HInstructionStringifier(block, closedWorld, namer);
assert(block.id != null);
tag("block", () {
printProperty("name", "B${block.id}");
@@ -113,12 +113,11 @@
}
class HInstructionStringifier implements HVisitor<String> {
- final Compiler compiler;
+ final ClosedWorld closedWorld;
+ final Namer namer;
final HBasicBlock currentBlock;
- HInstructionStringifier(this.currentBlock, this.compiler);
-
- ClosedWorld get closedWorld => compiler.closedWorld;
+ HInstructionStringifier(this.currentBlock, this.closedWorld, this.namer);
visit(HInstruction node) => '${node.accept(this)} ${node.instructionType}';
@@ -295,9 +294,7 @@
String visitInterceptor(HInterceptor node) {
String value = temporaryId(node.inputs[0]);
if (node.interceptedClasses != null) {
- JavaScriptBackend backend = compiler.backend;
- String cls =
- backend.namer.suffixForGetInterceptor(node.interceptedClasses);
+ String cls = namer.suffixForGetInterceptor(node.interceptedClasses);
return "Interceptor ($cls): $value";
}
return "Interceptor: $value";
diff --git a/pkg/compiler/lib/src/ssa/type_builder.dart b/pkg/compiler/lib/src/ssa/type_builder.dart
index 517c091..48a7d98 100644
--- a/pkg/compiler/lib/src/ssa/type_builder.dart
+++ b/pkg/compiler/lib/src/ssa/type_builder.dart
@@ -72,7 +72,7 @@
{SourceInformation sourceInformation}) {
assert(assertTypeInContext(type));
if (type is MethodTypeVariableType) {
- return builder.graph.addConstantNull(builder.compiler);
+ return builder.graph.addConstantNull(builder.closedWorld);
}
bool isClosure = member.enclosingElement.isClosure;
if (isClosure) {
@@ -177,7 +177,7 @@
argument = argument.unaliased;
if (argument.treatAsDynamic) {
// Represent [dynamic] as [null].
- return builder.graph.addConstantNull(builder.compiler);
+ return builder.graph.addConstantNull(builder.closedWorld);
}
if (argument.isTypeVariable) {
diff --git a/pkg/compiler/lib/src/ssa/types_propagation.dart b/pkg/compiler/lib/src/ssa/types_propagation.dart
index 6412197..dd21826 100644
--- a/pkg/compiler/lib/src/ssa/types_propagation.dart
+++ b/pkg/compiler/lib/src/ssa/types_propagation.dart
@@ -22,9 +22,7 @@
JavaScriptBackend get backend => compiler.backend;
String get name => 'type propagator';
- SsaTypePropagator(Compiler compiler)
- : this.compiler = compiler,
- this.closedWorld = compiler.closedWorld;
+ SsaTypePropagator(this.compiler, this.closedWorld);
TypeMask computeType(HInstruction instruction) {
return instruction.accept(this);
diff --git a/pkg/compiler/lib/src/ssa/value_range_analyzer.dart b/pkg/compiler/lib/src/ssa/value_range_analyzer.dart
index 67e861e..3f041a0 100644
--- a/pkg/compiler/lib/src/ssa/value_range_analyzer.dart
+++ b/pkg/compiler/lib/src/ssa/value_range_analyzer.dart
@@ -2,11 +2,11 @@
// 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 '../compiler.dart' show Compiler;
import '../constant_system_dart.dart';
import '../constants/constant_system.dart';
import '../constants/values.dart';
import '../js_backend/js_backend.dart';
+import '../js_backend/backend_helpers.dart';
import '../world.dart' show ClosedWorld;
import 'nodes.dart';
import 'optimize.dart';
@@ -601,18 +601,19 @@
*/
final Map<HInstruction, Range> ranges = new Map<HInstruction, Range>();
- final Compiler compiler;
- final ConstantSystem constantSystem;
+ final BackendHelpers backendHelpers;
+ final ClosedWorld closedWorld;
final ValueRangeInfo info;
final SsaOptimizerTask optimizer;
HGraph graph;
- SsaValueRangeAnalyzer(this.compiler, constantSystem, this.optimizer)
- : info = new ValueRangeInfo(constantSystem),
- this.constantSystem = constantSystem;
+ SsaValueRangeAnalyzer(
+ this.backendHelpers, ClosedWorld closedWorld, this.optimizer)
+ : info = new ValueRangeInfo(closedWorld.constantSystem),
+ this.closedWorld = closedWorld;
- ClosedWorld get closedWorld => compiler.closedWorld;
+ ConstantSystem get constantSystem => closedWorld.constantSystem;
void visitGraph(HGraph graph) {
this.graph = graph;
@@ -702,8 +703,7 @@
if (!fieldGet.receiver.isIndexablePrimitive(closedWorld)) {
return visitInstruction(fieldGet);
}
- JavaScriptBackend backend = compiler.backend;
- assert(fieldGet.element == backend.helpers.jsIndexableLength);
+ assert(fieldGet.element == backendHelpers.jsIndexableLength);
PositiveValue value = info.newPositiveValue(fieldGet);
// We know this range is above zero. To simplify the analysis, we
// put the zero value as the lower bound of this range. This
@@ -790,11 +790,11 @@
handleEqualityCheck(relational);
} else if (operation.apply(leftRange, rightRange)) {
relational.block
- .rewrite(relational, graph.addConstantBool(true, compiler));
+ .rewrite(relational, graph.addConstantBool(true, closedWorld));
relational.block.remove(relational);
} else if (negateOperation(operation).apply(leftRange, rightRange)) {
relational.block
- .rewrite(relational, graph.addConstantBool(false, compiler));
+ .rewrite(relational, graph.addConstantBool(false, closedWorld));
relational.block.remove(relational);
}
return info.newUnboundRange();
@@ -804,7 +804,7 @@
Range right = ranges[node.right];
Range left = ranges[node.left];
if (left.isSingleValue && right.isSingleValue && left == right) {
- node.block.rewrite(node, graph.addConstantBool(true, compiler));
+ node.block.rewrite(node, graph.addConstantBool(true, closedWorld));
node.block.remove(node);
}
}
diff --git a/pkg/compiler/lib/src/tracer.dart b/pkg/compiler/lib/src/tracer.dart
index e73e82a..0233143 100644
--- a/pkg/compiler/lib/src/tracer.dart
+++ b/pkg/compiler/lib/src/tracer.dart
@@ -7,10 +7,11 @@
import 'dart:async' show EventSink;
import '../compiler.dart' as api;
-import 'compiler.dart' show Compiler;
+import 'js_backend/namer.dart' show Namer;
import 'ssa/nodes.dart' as ssa show HGraph;
import 'ssa/ssa_tracer.dart' show HTracer;
import 'util/util.dart' show Indentation;
+import 'world.dart' show ClosedWorld;
/**
* If non-null, we only trace methods whose name match the regexp defined by the
@@ -26,14 +27,15 @@
* readable by IR Hydra.
*/
class Tracer extends TracerUtil {
- final Compiler compiler;
+ final ClosedWorld closedWorld;
+ final Namer namer;
bool traceActive = false;
final EventSink<String> output;
final bool isEnabled = TRACE_FILTER != null;
- Tracer(Compiler compiler, api.CompilerOutputProvider outputProvider)
- : this.compiler = compiler,
- output = TRACE_FILTER != null ? outputProvider('dart', 'cfg') : null;
+ Tracer(
+ this.closedWorld, this.namer, api.CompilerOutputProvider outputProvider)
+ : output = TRACE_FILTER != null ? outputProvider('dart', 'cfg') : null;
void traceCompilation(String methodName) {
if (!isEnabled) return;
@@ -49,7 +51,7 @@
void traceGraph(String name, var irObject) {
if (!traceActive) return;
if (irObject is ssa.HGraph) {
- new HTracer(output, compiler).traceGraph(name, irObject);
+ new HTracer(output, closedWorld, namer).traceGraph(name, irObject);
}
}
diff --git a/pkg/compiler/lib/src/types/constants.dart b/pkg/compiler/lib/src/types/constants.dart
index 60dbd90..c6cc7b8 100644
--- a/pkg/compiler/lib/src/types/constants.dart
+++ b/pkg/compiler/lib/src/types/constants.dart
@@ -5,119 +5,123 @@
library types.constants;
import '../common.dart';
+import '../constants/constant_system.dart' show ConstantSystem;
import '../compiler.dart' show Compiler;
import '../constants/values.dart';
-import '../js_backend/js_backend.dart' show SyntheticConstantKind;
+import '../js_backend/js_backend.dart'
+ show JavaScriptBackend, SyntheticConstantKind;
+import '../world.dart' show ClosedWorld;
import 'masks.dart';
/// Computes the [TypeMask] for the constant [value].
-TypeMask computeTypeMask(Compiler compiler, ConstantValue value) {
- return value.accept(const ConstantValueTypeMasks(), compiler);
+TypeMask computeTypeMask(ClosedWorld closedWorld, ConstantValue value) {
+ return value.accept(const ConstantValueTypeMasks(), closedWorld);
}
-class ConstantValueTypeMasks extends ConstantValueVisitor<TypeMask, Compiler> {
+class ConstantValueTypeMasks
+ extends ConstantValueVisitor<TypeMask, ClosedWorld> {
const ConstantValueTypeMasks();
@override
TypeMask visitConstructed(
- ConstructedConstantValue constant, Compiler compiler) {
- if (compiler.backend.isInterceptorClass(constant.type.element)) {
- return compiler.closedWorld.commonMasks.nonNullType;
+ ConstructedConstantValue constant, ClosedWorld closedWorld) {
+ if (closedWorld.backendClasses.isInterceptorClass(constant.type.element)) {
+ return closedWorld.commonMasks.nonNullType;
}
- return new TypeMask.nonNullExact(
- constant.type.element, compiler.closedWorld);
+ return new TypeMask.nonNullExact(constant.type.element, closedWorld);
}
@override
- TypeMask visitDeferred(DeferredConstantValue constant, Compiler compiler) {
- return constant.referenced.accept(this, compiler);
+ TypeMask visitDeferred(
+ DeferredConstantValue constant, ClosedWorld closedWorld) {
+ return constant.referenced.accept(this, closedWorld);
}
@override
- TypeMask visitDouble(DoubleConstantValue constant, Compiler compiler) {
+ TypeMask visitDouble(DoubleConstantValue constant, ClosedWorld closedWorld) {
// We have to recognize double constants that are 'is int'.
- if (compiler.backend.constantSystem.isInt(constant)) {
+ if (closedWorld.constantSystem.isInt(constant)) {
if (constant.isMinusZero) {
- return compiler.closedWorld.commonMasks.uint31Type;
+ return closedWorld.commonMasks.uint31Type;
} else {
assert(constant.isPositiveInfinity || constant.isNegativeInfinity);
- return compiler.closedWorld.commonMasks.intType;
+ return closedWorld.commonMasks.intType;
}
}
- return compiler.closedWorld.commonMasks.doubleType;
+ return closedWorld.commonMasks.doubleType;
}
@override
- TypeMask visitSynthetic(SyntheticConstantValue constant, Compiler compiler) {
+ TypeMask visitSynthetic(
+ SyntheticConstantValue constant, ClosedWorld closedWorld) {
switch (constant.valueKind) {
case SyntheticConstantKind.DUMMY_INTERCEPTOR:
return constant.payload;
case SyntheticConstantKind.EMPTY_VALUE:
return constant.payload;
case SyntheticConstantKind.TYPEVARIABLE_REFERENCE:
- return compiler.closedWorld.commonMasks.intType;
+ return closedWorld.commonMasks.intType;
case SyntheticConstantKind.NAME:
- return compiler.closedWorld.commonMasks.stringType;
+ return closedWorld.commonMasks.stringType;
default:
- DiagnosticReporter reporter = compiler.reporter;
- reporter.internalError(
- CURRENT_ELEMENT_SPANNABLE, "Unexpected DummyConstantKind.");
- return null;
+ throw new SpannableAssertionFailure(CURRENT_ELEMENT_SPANNABLE,
+ "Unexpected DummyConstantKind: ${constant.toStructuredText()}.");
}
}
@override
- TypeMask visitBool(BoolConstantValue constant, Compiler compiler) {
- return compiler.closedWorld.commonMasks.boolType;
+ TypeMask visitBool(BoolConstantValue constant, ClosedWorld closedWorld) {
+ return closedWorld.commonMasks.boolType;
}
@override
- TypeMask visitFunction(FunctionConstantValue constant, Compiler compiler) {
- return compiler.closedWorld.commonMasks.functionType;
+ TypeMask visitFunction(
+ FunctionConstantValue constant, ClosedWorld closedWorld) {
+ return closedWorld.commonMasks.functionType;
}
@override
- TypeMask visitInt(IntConstantValue constant, Compiler compiler) {
- if (constant.isUInt31()) return compiler.closedWorld.commonMasks.uint31Type;
- if (constant.isUInt32()) return compiler.closedWorld.commonMasks.uint32Type;
- if (constant.isPositive())
- return compiler.closedWorld.commonMasks.positiveIntType;
- return compiler.closedWorld.commonMasks.intType;
+ TypeMask visitInt(IntConstantValue constant, ClosedWorld closedWorld) {
+ if (constant.isUInt31()) return closedWorld.commonMasks.uint31Type;
+ if (constant.isUInt32()) return closedWorld.commonMasks.uint32Type;
+ if (constant.isPositive()) return closedWorld.commonMasks.positiveIntType;
+ return closedWorld.commonMasks.intType;
}
@override
TypeMask visitInterceptor(
- InterceptorConstantValue constant, Compiler compiler) {
- return compiler.closedWorld.commonMasks.nonNullType;
+ InterceptorConstantValue constant, ClosedWorld closedWorld) {
+ return closedWorld.commonMasks.nonNullType;
}
@override
- TypeMask visitList(ListConstantValue constant, Compiler compiler) {
- return compiler.closedWorld.commonMasks.constListType;
+ TypeMask visitList(ListConstantValue constant, ClosedWorld closedWorld) {
+ return closedWorld.commonMasks.constListType;
}
@override
- TypeMask visitMap(MapConstantValue constant, Compiler compiler) {
- return compiler.closedWorld.commonMasks.constMapType;
+ TypeMask visitMap(MapConstantValue constant, ClosedWorld closedWorld) {
+ return closedWorld.commonMasks.constMapType;
}
@override
- TypeMask visitNull(NullConstantValue constant, Compiler compiler) {
- return compiler.closedWorld.commonMasks.nullType;
+ TypeMask visitNull(NullConstantValue constant, ClosedWorld closedWorld) {
+ return closedWorld.commonMasks.nullType;
}
@override
- TypeMask visitNonConstant(NonConstantValue constant, Compiler compiler) {
- return compiler.closedWorld.commonMasks.nullType;
+ TypeMask visitNonConstant(
+ NonConstantValue constant, ClosedWorld closedWorld) {
+ return closedWorld.commonMasks.nullType;
}
@override
- TypeMask visitString(StringConstantValue constant, Compiler compiler) {
- return compiler.closedWorld.commonMasks.stringType;
+ TypeMask visitString(StringConstantValue constant, ClosedWorld closedWorld) {
+ return closedWorld.commonMasks.stringType;
}
@override
- TypeMask visitType(TypeConstantValue constant, Compiler compiler) {
- return compiler.closedWorld.commonMasks.typeType;
+ TypeMask visitType(TypeConstantValue constant, ClosedWorld closedWorld) {
+ return closedWorld.commonMasks.typeType;
}
}
diff --git a/pkg/compiler/lib/src/types/masks.dart b/pkg/compiler/lib/src/types/masks.dart
index bee132d..f44446a 100644
--- a/pkg/compiler/lib/src/types/masks.dart
+++ b/pkg/compiler/lib/src/types/masks.dart
@@ -67,6 +67,7 @@
TypeMask _fixedArrayType;
TypeMask _extendableArrayType;
TypeMask _unmodifiableArrayType;
+ TypeMask _interceptorType;
TypeMask get dynamicType => _dynamicType ??=
new TypeMask.subclass(closedWorld.coreClasses.objectClass, closedWorld);
@@ -164,6 +165,10 @@
_unmodifiableArrayType ??= new TypeMask.nonNullExact(
backendClasses.constListImplementation, closedWorld);
+ TypeMask get interceptorType =>
+ _interceptorType ??= new TypeMask.nonNullSubclass(
+ backendClasses.interceptorImplementation, closedWorld);
+
bool isTypedArray(TypeMask mask) {
// Just checking for [:TypedData:] is not sufficient, as it is an
// abstract class any user-defined class can implement. So we also
diff --git a/pkg/compiler/lib/src/universe/world_builder.dart b/pkg/compiler/lib/src/universe/world_builder.dart
index 130b7eb..cd676bd 100644
--- a/pkg/compiler/lib/src/universe/world_builder.dart
+++ b/pkg/compiler/lib/src/universe/world_builder.dart
@@ -172,6 +172,11 @@
/// The [OpenWorld] being created by this world builder.
// TODO(johnniwinther): Merge this with [ResolutionWorldBuilder].
OpenWorld get openWorld;
+
+ /// The closed world computed by this world builder.
+ ///
+ /// This is only available after the world builder has been closed.
+ ClosedWorld get closedWorldForTesting;
}
/// The type and kind of an instantiation registered through
@@ -425,7 +430,7 @@
/// and classes.
bool useInstantiationMap = false;
- OpenWorld _openWorld;
+ WorldImpl _openWorld;
final Backend _backend;
final Resolution _resolution;
@@ -443,6 +448,14 @@
OpenWorld get openWorld => _openWorld;
+ ClosedWorld get closedWorldForTesting {
+ if (!_openWorld.isClosed) {
+ throw new SpannableAssertionFailure(
+ NO_LOCATION_SPANNABLE, "The world builder has not yet been closed.");
+ }
+ return _openWorld;
+ }
+
/// All directly instantiated classes, that is, classes with a generative
/// constructor that has been called directly and not only through a
/// super-call.
diff --git a/pkg/compiler/lib/src/world.dart b/pkg/compiler/lib/src/world.dart
index 3de6d0f..76b2bc3 100644
--- a/pkg/compiler/lib/src/world.dart
+++ b/pkg/compiler/lib/src/world.dart
@@ -8,6 +8,7 @@
import 'closure.dart' show SynthesizedCallMethodElementX;
import 'common/backend_api.dart' show BackendClasses;
import 'common.dart';
+import 'constants/constant_system.dart';
import 'core_types.dart' show CoreTypes, CoreClasses, CommonElements;
import 'dart_types.dart';
import 'elements/elements.dart'
@@ -53,6 +54,8 @@
CommonMasks get commonMasks;
+ ConstantSystem get constantSystem;
+
/// Returns `true` if [cls] is either directly or indirectly instantiated.
bool isInstantiated(ClassElement cls);
@@ -908,6 +911,8 @@
CoreClasses get coreClasses => commonElements;
+ ConstantSystem get constantSystem => _backend.constantSystem;
+
/// Called to add [cls] to the set of known classes.
///
/// This ensures that class hierarchy queries can be performed on [cls] and
diff --git a/pkg/dart2js_incremental/lib/caching_compiler.dart b/pkg/dart2js_incremental/lib/caching_compiler.dart
index 8bf1c64..44d56a6 100644
--- a/pkg/dart2js_incremental/lib/caching_compiler.dart
+++ b/pkg/dart2js_incremental/lib/caching_compiler.dart
@@ -68,16 +68,6 @@
environment: environment));
backend = compiler.backend;
- full.Emitter emitter = backend.emitter.emitter;
-
- // Much like a scout, an incremental compiler is always prepared. For
- // mixins, classes, and lazy statics, at least.
- emitter
- ..needsClassSupport = true
- ..needsMixinSupport = true
- ..needsLazyInitializer = true
- ..needsStructuredMemberInfo = true;
-
Uri core = Uri.parse("dart:core");
return compiler.setupSdk().then((_) {
diff --git a/pkg/dev_compiler/lib/js/amd/dart_sdk.js b/pkg/dev_compiler/lib/js/amd/dart_sdk.js
index c28cb0b..2a94c9f 100644
--- a/pkg/dev_compiler/lib/js/amd/dart_sdk.js
+++ b/pkg/dev_compiler/lib/js/amd/dart_sdk.js
@@ -34096,6 +34096,17 @@
return result;
}
};
+ core.Function.is = function is_Function(o) {
+ return typeof o == "function";
+ };
+ core.Function.as = function as_Function(o) {
+ if (typeof o == "function" || o == null) return o;
+ return dart.as(o, core.Function);
+ };
+ core.Function._check = function check_String(o) {
+ if (typeof o == "function" || o == null) return o;
+ return dart.check(o, core.Function);
+ };
dart.setSignature(core.Function, {
statics: () => ({
apply: dart.definiteFunctionType(dart.dynamic, [core.Function, core.List], [MapOfSymbol$dynamic()]),
@@ -52686,7 +52697,7 @@
}
if (args != null) args = core.List.from(args[dartx.map](dart.dynamic)(js._convertToJS));
let fn = this[_jsObject][method];
- if (!(fn instanceof Function)) {
+ if (typeof fn !== "function") {
dart.throw(new core.NoSuchMethodError(this[_jsObject], core.Symbol.new(core.String._check(method)), args, dart.map({}, core.Symbol, dart.dynamic)));
}
return js._convertToDart(fn.apply(this[_jsObject], args));
@@ -52888,7 +52899,7 @@
});
js.JsArray = JsArray();
js._isBrowserType = function(o) {
- return o instanceof Blob || o instanceof Event || window.KeyRange && o instanceof KeyRange || o instanceof ImageData || o instanceof Node || window.TypedData && o instanceof TypedData || o instanceof Window;
+ return o instanceof Blob || o instanceof Event || window.KeyRange && o instanceof KeyRange || window.IDBKeyRange && o instanceof IDBKeyRange || o instanceof ImageData || o instanceof Node || window.Int8Array && o instanceof Int8Array.__proto__ || o instanceof Window;
};
dart.fn(js._isBrowserType, dynamicTobool$());
const _dartObj = Symbol('_dartObj');
@@ -52933,11 +52944,15 @@
} else if (js._DartObject.is(o) && dart.jsobject != dart.getReifiedType(o)) {
return o[_dartObj];
} else {
- return js._putIfAbsent(js._dartProxies, o, js._wrapToDart);
+ return js._wrapToDart(o);
}
};
dart.fn(js._convertToDart, dynamicToObject());
js._wrapToDart = function(o) {
+ return js.JsObject._check(js._putIfAbsent(js._dartProxies, o, js._wrapToDartHelper));
+ };
+ dart.fn(js._wrapToDart, dynamicToJsObject());
+ js._wrapToDartHelper = function(o) {
if (typeof o == "function") {
return new js.JsFunction._fromJs(o);
}
@@ -52946,7 +52961,7 @@
}
return new js.JsObject._fromJs(o);
};
- dart.fn(js._wrapToDart, dynamicToJsObject());
+ dart.fn(js._wrapToDartHelper, dynamicToJsObject());
dart.defineLazy(js, {
get _dartProxies() {
return new WeakMap();
@@ -59491,10 +59506,10 @@
return html$.Blob._check(html$.Blob._create_2(blobParts, bag));
}
static _create_1(parts) {
- return new Blob(parts);
+ return new window.Blob(parts);
}
static _create_2(parts, bag) {
- return new Blob(parts, bag);
+ return new window.Blob(parts, bag);
}
static _create_bag() {
return {};
diff --git a/pkg/dev_compiler/lib/js/common/dart_sdk.js b/pkg/dev_compiler/lib/js/common/dart_sdk.js
index 5a032f3..f2826b9 100644
--- a/pkg/dev_compiler/lib/js/common/dart_sdk.js
+++ b/pkg/dev_compiler/lib/js/common/dart_sdk.js
@@ -34096,6 +34096,17 @@
return result;
}
};
+ core.Function.is = function is_Function(o) {
+ return typeof o == "function";
+ };
+ core.Function.as = function as_Function(o) {
+ if (typeof o == "function" || o == null) return o;
+ return dart.as(o, core.Function);
+ };
+ core.Function._check = function check_String(o) {
+ if (typeof o == "function" || o == null) return o;
+ return dart.check(o, core.Function);
+ };
dart.setSignature(core.Function, {
statics: () => ({
apply: dart.definiteFunctionType(dart.dynamic, [core.Function, core.List], [MapOfSymbol$dynamic()]),
@@ -52686,7 +52697,7 @@
}
if (args != null) args = core.List.from(args[dartx.map](dart.dynamic)(js._convertToJS));
let fn = this[_jsObject][method];
- if (!(fn instanceof Function)) {
+ if (typeof fn !== "function") {
dart.throw(new core.NoSuchMethodError(this[_jsObject], core.Symbol.new(core.String._check(method)), args, dart.map({}, core.Symbol, dart.dynamic)));
}
return js._convertToDart(fn.apply(this[_jsObject], args));
@@ -52888,7 +52899,7 @@
});
js.JsArray = JsArray();
js._isBrowserType = function(o) {
- return o instanceof Blob || o instanceof Event || window.KeyRange && o instanceof KeyRange || o instanceof ImageData || o instanceof Node || window.TypedData && o instanceof TypedData || o instanceof Window;
+ return o instanceof Blob || o instanceof Event || window.KeyRange && o instanceof KeyRange || window.IDBKeyRange && o instanceof IDBKeyRange || o instanceof ImageData || o instanceof Node || window.Int8Array && o instanceof Int8Array.__proto__ || o instanceof Window;
};
dart.fn(js._isBrowserType, dynamicTobool$());
const _dartObj = Symbol('_dartObj');
@@ -52933,11 +52944,15 @@
} else if (js._DartObject.is(o) && dart.jsobject != dart.getReifiedType(o)) {
return o[_dartObj];
} else {
- return js._putIfAbsent(js._dartProxies, o, js._wrapToDart);
+ return js._wrapToDart(o);
}
};
dart.fn(js._convertToDart, dynamicToObject());
js._wrapToDart = function(o) {
+ return js.JsObject._check(js._putIfAbsent(js._dartProxies, o, js._wrapToDartHelper));
+ };
+ dart.fn(js._wrapToDart, dynamicToJsObject());
+ js._wrapToDartHelper = function(o) {
if (typeof o == "function") {
return new js.JsFunction._fromJs(o);
}
@@ -52946,7 +52961,7 @@
}
return new js.JsObject._fromJs(o);
};
- dart.fn(js._wrapToDart, dynamicToJsObject());
+ dart.fn(js._wrapToDartHelper, dynamicToJsObject());
dart.defineLazy(js, {
get _dartProxies() {
return new WeakMap();
@@ -59491,10 +59506,10 @@
return html$.Blob._check(html$.Blob._create_2(blobParts, bag));
}
static _create_1(parts) {
- return new Blob(parts);
+ return new window.Blob(parts);
}
static _create_2(parts, bag) {
- return new Blob(parts, bag);
+ return new window.Blob(parts, bag);
}
static _create_bag() {
return {};
diff --git a/pkg/dev_compiler/lib/js/es6/dart_sdk.js b/pkg/dev_compiler/lib/js/es6/dart_sdk.js
index a575b51..993d4b0 100644
--- a/pkg/dev_compiler/lib/js/es6/dart_sdk.js
+++ b/pkg/dev_compiler/lib/js/es6/dart_sdk.js
@@ -34094,6 +34094,17 @@
return result;
}
};
+core.Function.is = function is_Function(o) {
+ return typeof o == "function";
+};
+core.Function.as = function as_Function(o) {
+ if (typeof o == "function" || o == null) return o;
+ return dart.as(o, core.Function);
+};
+core.Function._check = function check_String(o) {
+ if (typeof o == "function" || o == null) return o;
+ return dart.check(o, core.Function);
+};
dart.setSignature(core.Function, {
statics: () => ({
apply: dart.definiteFunctionType(dart.dynamic, [core.Function, core.List], [MapOfSymbol$dynamic()]),
@@ -52684,7 +52695,7 @@
}
if (args != null) args = core.List.from(args[dartx.map](dart.dynamic)(js._convertToJS));
let fn = this[_jsObject][method];
- if (!(fn instanceof Function)) {
+ if (typeof fn !== "function") {
dart.throw(new core.NoSuchMethodError(this[_jsObject], core.Symbol.new(core.String._check(method)), args, dart.map({}, core.Symbol, dart.dynamic)));
}
return js._convertToDart(fn.apply(this[_jsObject], args));
@@ -52886,7 +52897,7 @@
});
js.JsArray = JsArray();
js._isBrowserType = function(o) {
- return o instanceof Blob || o instanceof Event || window.KeyRange && o instanceof KeyRange || o instanceof ImageData || o instanceof Node || window.TypedData && o instanceof TypedData || o instanceof Window;
+ return o instanceof Blob || o instanceof Event || window.KeyRange && o instanceof KeyRange || window.IDBKeyRange && o instanceof IDBKeyRange || o instanceof ImageData || o instanceof Node || window.Int8Array && o instanceof Int8Array.__proto__ || o instanceof Window;
};
dart.fn(js._isBrowserType, dynamicTobool());
const _dartObj = Symbol('_dartObj');
@@ -52931,11 +52942,15 @@
} else if (js._DartObject.is(o) && dart.jsobject != dart.getReifiedType(o)) {
return o[_dartObj];
} else {
- return js._putIfAbsent(js._dartProxies, o, js._wrapToDart);
+ return js._wrapToDart(o);
}
};
dart.fn(js._convertToDart, dynamicToObject());
js._wrapToDart = function(o) {
+ return js.JsObject._check(js._putIfAbsent(js._dartProxies, o, js._wrapToDartHelper));
+};
+dart.fn(js._wrapToDart, dynamicToJsObject());
+js._wrapToDartHelper = function(o) {
if (typeof o == "function") {
return new js.JsFunction._fromJs(o);
}
@@ -52944,7 +52959,7 @@
}
return new js.JsObject._fromJs(o);
};
-dart.fn(js._wrapToDart, dynamicToJsObject());
+dart.fn(js._wrapToDartHelper, dynamicToJsObject());
dart.defineLazy(js, {
get _dartProxies() {
return new WeakMap();
@@ -59489,10 +59504,10 @@
return html.Blob._check(html.Blob._create_2(blobParts, bag));
}
static _create_1(parts) {
- return new Blob(parts);
+ return new window.Blob(parts);
}
static _create_2(parts, bag) {
- return new Blob(parts, bag);
+ return new window.Blob(parts, bag);
}
static _create_bag() {
return {};
diff --git a/pkg/dev_compiler/lib/js/legacy/dart_sdk.js b/pkg/dev_compiler/lib/js/legacy/dart_sdk.js
index b5a3e61..d960ce5 100644
--- a/pkg/dev_compiler/lib/js/legacy/dart_sdk.js
+++ b/pkg/dev_compiler/lib/js/legacy/dart_sdk.js
@@ -34097,6 +34097,17 @@
return result;
}
};
+ core.Function.is = function is_Function(o) {
+ return typeof o == "function";
+ };
+ core.Function.as = function as_Function(o) {
+ if (typeof o == "function" || o == null) return o;
+ return dart.as(o, core.Function);
+ };
+ core.Function._check = function check_String(o) {
+ if (typeof o == "function" || o == null) return o;
+ return dart.check(o, core.Function);
+ };
dart.setSignature(core.Function, {
statics: () => ({
apply: dart.definiteFunctionType(dart.dynamic, [core.Function, core.List], [MapOfSymbol$dynamic()]),
@@ -52687,7 +52698,7 @@
}
if (args != null) args = core.List.from(args[dartx.map](dart.dynamic)(js._convertToJS));
let fn = this[_jsObject][method];
- if (!(fn instanceof Function)) {
+ if (typeof fn !== "function") {
dart.throw(new core.NoSuchMethodError(this[_jsObject], core.Symbol.new(core.String._check(method)), args, dart.map({}, core.Symbol, dart.dynamic)));
}
return js._convertToDart(fn.apply(this[_jsObject], args));
@@ -52889,7 +52900,7 @@
});
js.JsArray = JsArray();
js._isBrowserType = function(o) {
- return o instanceof Blob || o instanceof Event || window.KeyRange && o instanceof KeyRange || o instanceof ImageData || o instanceof Node || window.TypedData && o instanceof TypedData || o instanceof Window;
+ return o instanceof Blob || o instanceof Event || window.KeyRange && o instanceof KeyRange || window.IDBKeyRange && o instanceof IDBKeyRange || o instanceof ImageData || o instanceof Node || window.Int8Array && o instanceof Int8Array.__proto__ || o instanceof Window;
};
dart.fn(js._isBrowserType, dynamicTobool$());
const _dartObj = Symbol('_dartObj');
@@ -52934,11 +52945,15 @@
} else if (js._DartObject.is(o) && dart.jsobject != dart.getReifiedType(o)) {
return o[_dartObj];
} else {
- return js._putIfAbsent(js._dartProxies, o, js._wrapToDart);
+ return js._wrapToDart(o);
}
};
dart.fn(js._convertToDart, dynamicToObject());
js._wrapToDart = function(o) {
+ return js.JsObject._check(js._putIfAbsent(js._dartProxies, o, js._wrapToDartHelper));
+ };
+ dart.fn(js._wrapToDart, dynamicToJsObject());
+ js._wrapToDartHelper = function(o) {
if (typeof o == "function") {
return new js.JsFunction._fromJs(o);
}
@@ -52947,7 +52962,7 @@
}
return new js.JsObject._fromJs(o);
};
- dart.fn(js._wrapToDart, dynamicToJsObject());
+ dart.fn(js._wrapToDartHelper, dynamicToJsObject());
dart.defineLazy(js, {
get _dartProxies() {
return new WeakMap();
@@ -59492,10 +59507,10 @@
return html$.Blob._check(html$.Blob._create_2(blobParts, bag));
}
static _create_1(parts) {
- return new Blob(parts);
+ return new window.Blob(parts);
}
static _create_2(parts, bag) {
- return new Blob(parts, bag);
+ return new window.Blob(parts, bag);
}
static _create_bag() {
return {};
diff --git a/pkg/dev_compiler/lib/sdk/ddc_sdk.sum b/pkg/dev_compiler/lib/sdk/ddc_sdk.sum
index 1e77413..9ba0e1c 100644
--- a/pkg/dev_compiler/lib/sdk/ddc_sdk.sum
+++ b/pkg/dev_compiler/lib/sdk/ddc_sdk.sum
Binary files differ
diff --git a/pkg/dev_compiler/lib/src/analyzer/context.dart b/pkg/dev_compiler/lib/src/analyzer/context.dart
index 007a582..bdf5d16 100644
--- a/pkg/dev_compiler/lib/src/analyzer/context.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/context.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:args/args.dart' show ArgParser, ArgResults;
+import 'package:analyzer/src/command_line/arguments.dart';
import 'package:analyzer/file_system/file_system.dart'
show ResourceProvider, ResourceUriResolver;
import 'package:analyzer/file_system/physical_file_system.dart'
@@ -24,11 +25,13 @@
/// Options used to set up Source URI resolution in the analysis context.
class AnalyzerOptions {
+ final ContextBuilderOptions contextBuilderOptions;
+
/// Custom URI mappings, such as "dart:foo" -> "path/to/foo.dart"
final Map<String, String> customUrlMappings;
/// Package root when resolving 'package:' urls the standard way.
- final String packageRoot;
+ String get packageRoot => contextBuilderOptions.defaultPackagesDirectoryPath;
/// List of summary file paths.
final List<String> summaryPaths;
@@ -39,39 +42,52 @@
/// Path to the dart-sdk summary. If this is set, it will be used in favor
/// of the unsummarized one.
- final String dartSdkSummaryPath;
+ String get dartSdkSummaryPath => contextBuilderOptions.dartSdkSummaryPath;
/// Defined variables used by `bool.fromEnvironment` etc.
- final Map<String, String> declaredVariables;
+ Map<String, String> get declaredVariables =>
+ contextBuilderOptions.declaredVariables;
- AnalyzerOptions(
- {this.summaryPaths: const [],
+ AnalyzerOptions._(
+ {this.contextBuilderOptions,
+ this.summaryPaths: const [],
String dartSdkPath,
- this.dartSdkSummaryPath,
- this.customUrlMappings: const {},
- this.packageRoot: null,
- this.declaredVariables: const {}})
- : dartSdkPath = dartSdkPath ?? getSdkDir().path;
+ this.customUrlMappings: const {}})
+ : dartSdkPath = dartSdkPath ?? getSdkDir().path {
+ contextBuilderOptions.declaredVariables ??= const {};
+ }
- factory AnalyzerOptions.fromArguments(
- ArgResults args, Map<String, String> declaredVariables) {
- var sdkPath = args['dart-sdk'] ?? getSdkDir().path;
- var sdkSummaryPath = args['dart-sdk-summary'];
+ factory AnalyzerOptions.basic(
+ {String dartSdkPath,
+ String dartSdkSummaryPath,
+ List<String> summaryPaths}) {
+ var contextBuilderOptions = new ContextBuilderOptions();
+ contextBuilderOptions.dartSdkSummaryPath = dartSdkSummaryPath;
- if (sdkSummaryPath == null) {
- sdkSummaryPath = path.join(sdkPath, 'lib', '_internal', 'ddc_sdk.sum');
- } else if (sdkSummaryPath == 'build') {
+ return new AnalyzerOptions._(
+ contextBuilderOptions: contextBuilderOptions,
+ dartSdkPath: dartSdkPath,
+ summaryPaths: summaryPaths);
+ }
+
+ factory AnalyzerOptions.fromArguments(ArgResults args,
+ {String dartSdkSummaryPath, List<String> summaryPaths}) {
+ var contextBuilderOptions = createContextBuilderOptions(args);
+
+ if (dartSdkSummaryPath != null)
+ contextBuilderOptions.dartSdkSummaryPath = dartSdkSummaryPath;
+ contextBuilderOptions.dartSdkSummaryPath ??=
+ path.join(args['dart-sdk'], 'lib', '_internal', 'ddc_sdk.sum');
+ if (contextBuilderOptions.dartSdkSummaryPath == 'build') {
// For building the SDK, we explicitly set the path to none.
- sdkSummaryPath = null;
+ contextBuilderOptions.dartSdkSummaryPath = null;
}
- return new AnalyzerOptions(
- summaryPaths: args['summary'] as List<String>,
- dartSdkPath: sdkPath,
- dartSdkSummaryPath: sdkSummaryPath,
- customUrlMappings: _parseUrlMappings(args['url-mapping']),
- packageRoot: args['package-root'],
- declaredVariables: declaredVariables);
+ return new AnalyzerOptions._(
+ contextBuilderOptions: contextBuilderOptions,
+ summaryPaths: summaryPaths ?? args['summary'] as List<String>,
+ dartSdkPath: args['dart-sdk'],
+ customUrlMappings: _parseUrlMappings(args['url-mapping']));
}
static void addArguments(ArgParser parser, {bool hide: true}) {
diff --git a/pkg/dev_compiler/lib/src/compiler/code_generator.dart b/pkg/dev_compiler/lib/src/compiler/code_generator.dart
index 137c16e..46ddce3 100644
--- a/pkg/dev_compiler/lib/src/compiler/code_generator.dart
+++ b/pkg/dev_compiler/lib/src/compiler/code_generator.dart
@@ -126,6 +126,7 @@
final ClassElement numClass;
final ClassElement objectClass;
final ClassElement stringClass;
+ final ClassElement functionClass;
final ClassElement symbolClass;
ConstFieldVisitor _constants;
@@ -171,6 +172,7 @@
nullClass = _getLibrary(c, 'dart:core').getType('Null'),
objectClass = _getLibrary(c, 'dart:core').getType('Object'),
stringClass = _getLibrary(c, 'dart:core').getType('String'),
+ functionClass = _getLibrary(c, 'dart:core').getType('Function'),
symbolClass = _getLibrary(c, 'dart:_internal').getType('Symbol'),
dartJSLibrary = _getLibrary(c, 'dart:js');
@@ -930,6 +932,25 @@
[className, _runtimeModule, className]));
return;
}
+ if (classElem == functionClass) {
+ body.add(js.statement(
+ '#.is = function is_Function(o) { return typeof o == "function"; }',
+ className));
+ body.add(js.statement(
+ '#.as = function as_Function(o) {'
+ ' if (typeof o == "function" || o == null) return o;'
+ ' return #.as(o, #);'
+ '}',
+ [className, _runtimeModule, className]));
+ body.add(js.statement(
+ '#._check = function check_String(o) {'
+ ' if (typeof o == "function" || o == null) return o;'
+ ' return #.check(o, #);'
+ '}',
+ [className, _runtimeModule, className]));
+ return;
+ }
+
if (classElem == intClass) {
body.add(js.statement(
'#.is = function is_int(o) {'
diff --git a/pkg/dev_compiler/lib/src/compiler/command.dart b/pkg/dev_compiler/lib/src/compiler/command.dart
index 7ee4c5c..102f33a 100644
--- a/pkg/dev_compiler/lib/src/compiler/command.dart
+++ b/pkg/dev_compiler/lib/src/compiler/command.dart
@@ -5,8 +5,7 @@
import 'dart:io';
import 'package:analyzer/src/command_line/arguments.dart'
show
- defineDDCAnalysisArguments,
- extractDefinedVariables,
+ defineAnalysisArguments,
filterUnknownArguments,
ignoreUnrecognizedFlagsFlag;
import 'package:analyzer/src/generated/source.dart' show Source;
@@ -29,22 +28,29 @@
/// worker support.
int compile(List<String> args, {void printFn(Object obj)}) {
printFn ??= print;
+
ArgResults argResults;
- var declaredVars = <String, String>{};
+ AnalyzerOptions analyzerOptions;
try {
- args = extractDefinedVariables(args, declaredVars);
var parser = _argParser();
if (args.contains('--$ignoreUnrecognizedFlagsFlag')) {
args = filterUnknownArguments(args, parser);
}
argResults = parser.parse(args);
- _verbose = argResults['verbose'];
+ analyzerOptions = new AnalyzerOptions.fromArguments(argResults);
} on FormatException catch (error) {
printFn('$error\n\n$_usageMessage');
return 64;
}
+
+ _verbose = argResults['verbose'];
+ if (argResults['help']) {
+ printFn(_usageMessage);
+ return 0;
+ }
+
try {
- _compile(argResults, declaredVars, printFn);
+ _compile(argResults, analyzerOptions, printFn);
return 0;
} on UsageException catch (error) {
// Incorrect usage, input file not found, etc.
@@ -97,7 +103,7 @@
..addOption('library-root',
help: 'Root of source files.\n'
'Generated library names are relative to this root.');
- defineDDCAnalysisArguments(argParser, hide: hide);
+ defineAnalysisArguments(argParser, hide: hide, ddc: true);
addModuleFormatOptions(argParser, allowMultiple: true, hide: hide);
AnalyzerOptions.addArguments(argParser, hide: hide);
CompilerOptions.addArguments(argParser, hide: hide);
@@ -113,14 +119,9 @@
return false;
}
-void _compile(ArgResults argResults, Map<String, String> declaredVars,
+void _compile(ArgResults argResults, AnalyzerOptions analyzerOptions,
void printFn(Object obj)) {
- if (argResults['help']) {
- printFn(_usageMessage);
- return;
- }
- var compiler = new ModuleCompiler(
- new AnalyzerOptions.fromArguments(argResults, declaredVars));
+ var compiler = new ModuleCompiler(analyzerOptions);
var compilerOpts = new CompilerOptions.fromArguments(argResults);
var outPaths = argResults['out'] as List<String>;
var moduleFormats = parseModuleFormatOption(argResults);
diff --git a/pkg/dev_compiler/test/browser/language_tests.js b/pkg/dev_compiler/test/browser/language_tests.js
index 2e2c6d4..56f7196 100644
--- a/pkg/dev_compiler/test/browser/language_tests.js
+++ b/pkg/dev_compiler/test/browser/language_tests.js
@@ -471,8 +471,6 @@
'interactive_test': async_unittest,
'isolates_test': async_unittest,
- // Failing on "identical JS objects should have identical proxies".
- 'js_test': 'fail',
'js_interop_1_test': async_unittest,
// Failing because accessing "zSomeInvalidName" does not throw.
diff --git a/pkg/dev_compiler/test/codegen_test.dart b/pkg/dev_compiler/test/codegen_test.dart
index 66ee94e..4c4446c 100644
--- a/pkg/dev_compiler/test/codegen_test.dart
+++ b/pkg/dev_compiler/test/codegen_test.dart
@@ -21,7 +21,7 @@
UriBasedDirective,
parseDirectives;
import 'package:analyzer/src/command_line/arguments.dart'
- show extractDefinedVariables;
+ show defineAnalysisArguments;
import 'package:analyzer/src/dart/ast/ast.dart';
import 'package:analyzer/src/generated/source.dart' show Source;
import 'package:args/args.dart' show ArgParser, ArgResults;
@@ -79,7 +79,7 @@
.where((p) => p.endsWith('.sum'))
.toList();
- var sharedCompiler = new ModuleCompiler(new AnalyzerOptions(
+ var sharedCompiler = new ModuleCompiler(new AnalyzerOptions.basic(
dartSdkSummaryPath: sdkSummaryFile, summaryPaths: summaryPaths));
var testDirs = [
@@ -104,6 +104,8 @@
// Our default compiler options. Individual tests can override these.
var defaultOptions = ['--no-source-map', '--no-summarize'];
var compileArgParser = new ArgParser();
+ defineAnalysisArguments(compileArgParser, ddc: true);
+ AnalyzerOptions.addArguments(compileArgParser);
CompilerOptions.addArguments(compileArgParser);
addModuleFormatOptions(compileArgParser);
@@ -138,16 +140,12 @@
args.addAll(matchedArgs.where((s) => !ignoreOptions.contains(s)));
}
- var declaredVars = <String, String>{};
- args = extractDefinedVariables(args, declaredVars);
- ArgResults argResults;
- try {
- argResults = compileArgParser.parse(args);
- } catch (e) {
- print('Failed to parse $args');
- rethrow;
- }
+ ArgResults argResults = compileArgParser.parse(args);
+ var analyzerOptions = new AnalyzerOptions.fromArguments(argResults,
+ dartSdkSummaryPath: sdkSummaryFile, summaryPaths: summaryPaths);
+
var options = new CompilerOptions.fromArguments(argResults);
+
var moduleFormat = parseModuleFormatOption(argResults).first;
// Collect any other files we've imported.
@@ -157,11 +155,8 @@
name, path.dirname(testFile), files.toList(), _moduleForLibrary);
var compiler = sharedCompiler;
- if (declaredVars.isNotEmpty) {
- compiler = new ModuleCompiler(new AnalyzerOptions(
- dartSdkSummaryPath: sdkSummaryFile,
- summaryPaths: summaryPaths,
- declaredVariables: declaredVars));
+ if (analyzerOptions.declaredVariables.isNotEmpty) {
+ compiler = new ModuleCompiler(analyzerOptions);
}
var module = compiler.compile(unit, options);
diff --git a/pkg/dev_compiler/tool/input_sdk/lib/html/dart2js/html_dart2js.dart b/pkg/dev_compiler/tool/input_sdk/lib/html/dart2js/html_dart2js.dart
index e103c7d..d24f6da 100644
--- a/pkg/dev_compiler/tool/input_sdk/lib/html/dart2js/html_dart2js.dart
+++ b/pkg/dev_compiler/tool/input_sdk/lib/html/dart2js/html_dart2js.dart
@@ -1214,8 +1214,8 @@
return _create_2(blobParts, bag);
}
- static _create_1(parts) => JS('Blob', 'new Blob(#)', parts);
- static _create_2(parts, bag) => JS('Blob', 'new Blob(#, #)', parts, bag);
+ static _create_1(parts) => JS('Blob', 'new window.Blob(#)', parts);
+ static _create_2(parts, bag) => JS('Blob', 'new window.Blob(#, #)', parts, bag);
static _create_bag() => JS('var', '{}');
static _bag_set(bag, key, value) { JS('void', '#[#] = #', bag, key, value); }
diff --git a/pkg/dev_compiler/tool/input_sdk/lib/js/dart2js/js_dart2js.dart b/pkg/dev_compiler/tool/input_sdk/lib/js/dart2js/js_dart2js.dart
index 34636a7..3fc25ad 100644
--- a/pkg/dev_compiler/tool/input_sdk/lib/js/dart2js/js_dart2js.dart
+++ b/pkg/dev_compiler/tool/input_sdk/lib/js/dart2js/js_dart2js.dart
@@ -273,7 +273,7 @@
}
if (args != null) args = new List.from(args.map(_convertToJS));
var fn = JS('', '#[#]', _jsObject, method);
- if (!JS('bool', '# instanceof Function', fn)) {
+ if (JS('bool', 'typeof(#) !== "function"', fn)) {
throw new NoSuchMethodError(_jsObject, new Symbol(method), args, {});
}
return _convertToDart(JS('', '#.apply(#, #)', fn, _jsObject, args));
@@ -435,10 +435,12 @@
'# instanceof Blob || '
'# instanceof Event || '
'(window.KeyRange && # instanceof KeyRange) || '
+ '(window.IDBKeyRange && # instanceof IDBKeyRange) || '
'# instanceof ImageData || '
'# instanceof Node || '
- '(window.TypedData && # instanceof TypedData) || '
- '# instanceof Window', o, o, o, o, o, o, o);
+ // Int8Array.__proto__ is TypedArray.
+ '(window.Int8Array && # instanceof Int8Array.__proto__) || '
+ '# instanceof Window', o, o, o, o, o, o, o, o);
class _DartObject {
final _dartObj;
@@ -491,11 +493,13 @@
JS('bool', 'dart.jsobject != dart.getReifiedType(#)', o)) {
return o._dartObj;
} else {
- return _putIfAbsent(_dartProxies, o, _wrapToDart);
+ return _wrapToDart(o);
}
}
-JsObject _wrapToDart(o) {
+JsObject _wrapToDart(o) => _putIfAbsent(_dartProxies, o, _wrapToDartHelper);
+
+JsObject _wrapToDartHelper(o) {
if (JS('bool', 'typeof # == "function"', o)) {
return new JsFunction._fromJs(o);
}
diff --git a/pkg/dev_compiler/web/web_command.dart b/pkg/dev_compiler/web/web_command.dart
index bc4c1ad..3462633 100644
--- a/pkg/dev_compiler/web/web_command.dart
+++ b/pkg/dev_compiler/web/web_command.dart
@@ -116,7 +116,7 @@
var fileResolvers = [summaryResolver, resourceUriResolver];
var compiler = new ModuleCompiler(
- new AnalyzerOptions(dartSdkPath: '/dart-sdk'),
+ new AnalyzerOptions.basic(dartSdkPath: '/dart-sdk'),
sdkResolver: sdkResolver,
fileResolvers: fileResolvers,
resourceProvider: resourceProvider);
diff --git a/pkg/front_end/lib/compiler_options.dart b/pkg/front_end/lib/compiler_options.dart
index fdebf67..5230f4e 100644
--- a/pkg/front_end/lib/compiler_options.dart
+++ b/pkg/front_end/lib/compiler_options.dart
@@ -36,6 +36,8 @@
///
/// If `null`, the ".packages" file will be found via the standard
/// package_config search algorithm.
+ ///
+ /// If the empty string, no packages file will be used.
String packagesFilePath;
/// Paths to the input summary files (excluding the SDK summary). These files
diff --git a/pkg/front_end/lib/dependency_grapher.dart b/pkg/front_end/lib/dependency_grapher.dart
index 7f9fbc8..a743168 100644
--- a/pkg/front_end/lib/dependency_grapher.dart
+++ b/pkg/front_end/lib/dependency_grapher.dart
@@ -12,6 +12,7 @@
import 'package:front_end/src/async_dependency_walker.dart';
import 'package:front_end/src/base/uri_resolver.dart';
import 'package:front_end/src/scanner/scanner.dart';
+import 'package:package_config/packages_file.dart' as package_config;
import 'compiler_options.dart';
@@ -22,11 +23,23 @@
/// in the program.
Future<Graph> graphForProgram(
List<Uri> sources, CompilerOptions options) async {
- var packages = <String, Uri>{}; // TODO(paulberry): support packages
+ Map<String, Uri> packages;
+ if (options.packagesFilePath == null) {
+ throw new UnimplementedError(); // TODO(paulberry): search for .packages
+ } else if (options.packagesFilePath.isEmpty) {
+ packages = {};
+ } else {
+ var contents = await options.fileSystem
+ .entityForPath(options.packagesFilePath)
+ .readAsBytes();
+ var baseLocation =
+ options.fileSystem.context.toUri(options.packagesFilePath);
+ packages = package_config.parse(contents, baseLocation);
+ }
var sdkLibraries = <String, Uri>{}; // TODO(paulberry): support SDK libraries
var uriResolver =
new UriResolver(packages, sdkLibraries, options.fileSystem.context);
- var walker = new _Walker(options.fileSystem, uriResolver);
+ var walker = new _Walker(options.fileSystem, uriResolver, options.compileSdk);
var startingPoint = new _StartingPoint(walker, sources);
await walker.walk(startingPoint);
return walker.graph;
@@ -97,8 +110,9 @@
final UriResolver uriResolver;
final _nodesByUri = <Uri, _WalkerNode>{};
final graph = new Graph._();
+ final bool compileSdk;
- _Walker(this.fileSystem, this.uriResolver);
+ _Walker(this.fileSystem, this.uriResolver, this.compileSdk);
@override
Future<Null> evaluate(_WalkerNode v) {
@@ -124,6 +138,7 @@
}
class _WalkerNode extends Node<_WalkerNode> {
+ static final dartCoreUri = Uri.parse('dart:core');
final _Walker walker;
final Uri uri;
final LibraryNode library;
@@ -136,14 +151,30 @@
Future<List<_WalkerNode>> computeDependencies() async {
var dependencies = <_WalkerNode>[];
// TODO(paulberry): add error recovery if the file can't be read.
- var contents = await walker.fileSystem
- .entityForPath(walker.uriResolver.resolve(uri))
- .readAsString();
+ var path = walker.uriResolver.resolve(uri);
+ if (path == null) {
+ // TODO(paulberry): If an error reporter was provided, report the error
+ // in the proper way and continue.
+ throw new StateError('Invalid URI: $uri');
+ }
+ var contents = await walker.fileSystem.entityForPath(path).readAsString();
var scanner = new _Scanner(contents);
var token = scanner.tokenize();
// TODO(paulberry): report errors.
var parser = new Parser(null, AnalysisErrorListener.NULL_LISTENER);
var unit = parser.parseDirectives(token);
+ bool coreUriFound = false;
+ void handleDependency(Uri referencedUri) {
+ _WalkerNode dependencyNode = walker.nodeForUri(referencedUri);
+ library.dependencies.add(dependencyNode.library);
+ if (referencedUri.scheme != 'dart' || walker.compileSdk) {
+ dependencies.add(dependencyNode);
+ }
+ if (referencedUri == dartCoreUri) {
+ coreUriFound = true;
+ }
+ }
+
for (var directive in unit.directives) {
if (directive is UriBasedDirective) {
// TODO(paulberry): when we support SDK libraries, we'll need more
@@ -152,12 +183,13 @@
if (directive is PartDirective) {
library.parts.add(referencedUri);
} else {
- _WalkerNode dependencyNode = walker.nodeForUri(referencedUri);
- dependencies.add(dependencyNode);
- library.dependencies.add(dependencyNode.library);
+ handleDependency(referencedUri);
}
}
}
+ if (!coreUriFound) {
+ handleDependency(dartCoreUri);
+ }
return dependencies;
}
}
diff --git a/pkg/front_end/test/dependency_grapher_test.dart b/pkg/front_end/test/dependency_grapher_test.dart
index 34640c6..bcfca56 100644
--- a/pkg/front_end/test/dependency_grapher_test.dart
+++ b/pkg/front_end/test/dependency_grapher_test.dart
@@ -20,7 +20,8 @@
@reflectiveTest
class DependencyGrapherTest {
LibraryNode checkLibrary(LibraryCycleNode cycle, String uri,
- {List<String> dependencies: const [], List<String> parts: const []}) {
+ {List<String> dependencies: const ['dart:core'],
+ List<String> parts: const []}) {
var library = cycle.libraries[Uri.parse(uri)];
expect('${library.uri}', uri);
expect(library.dependencies.map((dep) => '${dep.uri}'),
@@ -30,7 +31,7 @@
}
Future<List<LibraryCycleNode>> getCycles(Map<String, String> contents,
- [List<String> startingPoints]) async {
+ {List<String> startingPoints, String packagesFilePath = ''}) async {
// If no starting points given, assume the first entry in [contents] is the
// single starting point.
startingPoints ??= [contents.keys.first];
@@ -41,7 +42,8 @@
// TODO(paulberry): implement and test other option possibilities.
var options = new CompilerOptions()
..fileSystem = fileSystem
- ..chaseDependencies = true;
+ ..chaseDependencies = true
+ ..packagesFilePath = packagesFilePath;
var graph = await graphForProgram(
startingPoints.map(pathos.posix.toUri).toList(), options);
return graph.topologicallySortedCycles;
@@ -56,6 +58,15 @@
return result;
}
+ test_explicitCoreDependency() async {
+ // If "dart:core" is explicitly imported, there shouldn't be two imports of
+ // "dart:core", just one.
+ var cycles = await getCycles({'/foo.dart': 'import "dart:core";'});
+ expect(cycles, hasLength(1));
+ expect(cycles[0].libraries, hasLength(1));
+ checkLibrary(cycles[0], 'file:///foo.dart');
+ }
+
test_exportDependency() async {
var cycles =
await getCycles({'/foo.dart': 'export "bar.dart";', '/bar.dart': ''});
@@ -64,7 +75,7 @@
checkLibrary(cycles[0], 'file:///bar.dart');
expect(cycles[1].libraries, hasLength(1));
checkLibrary(cycles[1], 'file:///foo.dart',
- dependencies: ['file:///bar.dart']);
+ dependencies: ['file:///bar.dart', 'dart:core']);
}
test_importDependency() async {
@@ -75,7 +86,7 @@
checkLibrary(cycles[0], 'file:///bar.dart');
expect(cycles[1].libraries, hasLength(1));
checkLibrary(cycles[1], 'file:///foo.dart',
- dependencies: ['file:///bar.dart']);
+ dependencies: ['file:///bar.dart', 'dart:core']);
}
test_multipleStartingPoints() async {
@@ -83,7 +94,7 @@
'/a.dart': 'import "c.dart";',
'/b.dart': 'import "c.dart";',
'/c.dart': ''
- }, [
+ }, startingPoints: [
'/a.dart',
'/b.dart'
]);
@@ -94,9 +105,27 @@
// reproducibility.
List<LibraryCycleNode> otherCycles = sortCycles(cycles.sublist(1));
checkLibrary(otherCycles[0], 'file:///a.dart',
- dependencies: ['file:///c.dart']);
+ dependencies: ['file:///c.dart', 'dart:core']);
checkLibrary(otherCycles[1], 'file:///b.dart',
- dependencies: ['file:///c.dart']);
+ dependencies: ['file:///c.dart', 'dart:core']);
+ }
+
+ test_packages() async {
+ var cycles = await getCycles({
+ '/foo.dart': 'import "package:foo/bar.dart";',
+ '/.packages': 'foo:pkg/foo/lib\nbar:pkg/bar/lib\n',
+ '/pkg/foo/lib/bar.dart': 'import "package:bar/baz.dart";',
+ '/pkg/bar/lib/baz.dart': ''
+ }, packagesFilePath: '/.packages');
+ expect(cycles, hasLength(3));
+ expect(cycles[0].libraries, hasLength(1));
+ checkLibrary(cycles[0], 'package:bar/baz.dart');
+ expect(cycles[1].libraries, hasLength(1));
+ checkLibrary(cycles[1], 'package:foo/bar.dart',
+ dependencies: ['package:bar/baz.dart', 'dart:core']);
+ expect(cycles[2].libraries, hasLength(1));
+ checkLibrary(cycles[2], 'file:///foo.dart',
+ dependencies: ['package:foo/bar.dart', 'dart:core']);
}
test_parts() async {
@@ -123,13 +152,23 @@
checkLibrary(cycles[0], 'file:///b/f.dart');
expect(cycles[1].libraries, hasLength(1));
checkLibrary(cycles[1], 'file:///b/d/e.dart',
- dependencies: ['file:///b/f.dart']);
+ dependencies: ['file:///b/f.dart', 'dart:core']);
expect(cycles[2].libraries, hasLength(1));
checkLibrary(cycles[2], 'file:///b/c.dart',
- dependencies: ['file:///b/d/e.dart']);
+ dependencies: ['file:///b/d/e.dart', 'dart:core']);
expect(cycles[3].libraries, hasLength(1));
checkLibrary(cycles[3], 'file:///a.dart',
- dependencies: ['file:///b/c.dart']);
+ dependencies: ['file:///b/c.dart', 'dart:core']);
+ }
+
+ test_sdkDependency() async {
+ // Dependencies on the SDK should be recorded even if SDK libraries aren't
+ // being included in the graph.
+ var cycles = await getCycles({'/foo.dart': 'import "dart:async";'});
+ expect(cycles, hasLength(1));
+ expect(cycles[0].libraries, hasLength(1));
+ checkLibrary(cycles[0], 'file:///foo.dart',
+ dependencies: ['dart:core', 'dart:async']);
}
test_simpleCycle() async {
@@ -138,9 +177,9 @@
expect(cycles, hasLength(1));
expect(cycles[0].libraries, hasLength(2));
var foo = checkLibrary(cycles[0], 'file:///foo.dart',
- dependencies: ['file:///bar.dart']);
+ dependencies: ['file:///bar.dart', 'dart:core']);
var bar = checkLibrary(cycles[0], 'file:///bar.dart',
- dependencies: ['file:///foo.dart']);
+ dependencies: ['file:///foo.dart', 'dart:core']);
expect(foo.dependencies[0], same(bar));
expect(bar.dependencies[0], same(foo));
}
diff --git a/runtime/bin/directory_android.cc b/runtime/bin/directory_android.cc
index 49077a3..b4ad7c0 100644
--- a/runtime/bin/directory_android.cc
+++ b/runtime/bin/directory_android.cc
@@ -351,6 +351,9 @@
if (S_ISDIR(entry_info.st_mode)) {
return EXISTS;
} else {
+ // An OSError may be constructed based on the return value of this
+ // function, so set errno to something that makes sense.
+ errno = ENOTDIR;
return DOES_NOT_EXIST;
}
} else {
diff --git a/runtime/bin/directory_fuchsia.cc b/runtime/bin/directory_fuchsia.cc
index 94a86d1..9259bd0 100644
--- a/runtime/bin/directory_fuchsia.cc
+++ b/runtime/bin/directory_fuchsia.cc
@@ -249,6 +249,9 @@
if (S_ISDIR(entry_info.st_mode)) {
return EXISTS;
} else {
+ // An OSError may be constructed based on the return value of this
+ // function, so set errno to something that makes sense.
+ errno = ENOTDIR;
return DOES_NOT_EXIST;
}
} else {
@@ -352,6 +355,8 @@
}
return NO_RETRY_EXPECTED(rmdir(dir_name)) == 0;
} else {
+ // TODO(MG-416): After the issue is addressed, this can use the same code
+ // as on Linux, etc.
UNIMPLEMENTED();
return false;
}
diff --git a/runtime/bin/directory_linux.cc b/runtime/bin/directory_linux.cc
index 357a580..f2a064a 100644
--- a/runtime/bin/directory_linux.cc
+++ b/runtime/bin/directory_linux.cc
@@ -360,6 +360,9 @@
if (S_ISDIR(entry_info.st_mode)) {
return EXISTS;
} else {
+ // An OSError may be constructed based on the return value of this
+ // function, so set errno to something that makes sense.
+ errno = ENOTDIR;
return DOES_NOT_EXIST;
}
} else {
diff --git a/runtime/bin/directory_macos.cc b/runtime/bin/directory_macos.cc
index b24b9c8..ca0d41b 100644
--- a/runtime/bin/directory_macos.cc
+++ b/runtime/bin/directory_macos.cc
@@ -351,6 +351,9 @@
if (S_ISDIR(entry_info.st_mode)) {
return EXISTS;
} else {
+ // An OSError may be constructed based on the return value of this
+ // function, so set errno to something that makes sense.
+ errno = ENOTDIR;
return DOES_NOT_EXIST;
}
} else {
diff --git a/runtime/bin/file_fuchsia.cc b/runtime/bin/file_fuchsia.cc
index bda6113..ff08043 100644
--- a/runtime/bin/file_fuchsia.cc
+++ b/runtime/bin/file_fuchsia.cc
@@ -16,6 +16,7 @@
#include <unistd.h> // NOLINT
#include "bin/builtin.h"
+#include "bin/fdutils.h"
#include "bin/log.h"
#include "platform/signal_blocker.h"
#include "platform/utils.h"
@@ -280,7 +281,48 @@
bool File::Copy(const char* old_path, const char* new_path) {
- UNIMPLEMENTED();
+ File::Type type = File::GetType(old_path, true);
+ if (type == kIsFile) {
+ struct stat64 st;
+ if (NO_RETRY_EXPECTED(stat64(old_path, &st)) != 0) {
+ return false;
+ }
+ int old_fd = NO_RETRY_EXPECTED(open64(old_path, O_RDONLY | O_CLOEXEC));
+ if (old_fd < 0) {
+ return false;
+ }
+ int new_fd = NO_RETRY_EXPECTED(
+ open64(new_path, O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC, st.st_mode));
+ if (new_fd < 0) {
+ VOID_TEMP_FAILURE_RETRY(close(old_fd));
+ return false;
+ }
+ // TODO(MG-429): Use sendfile/copyfile or equivalent when there is one.
+ intptr_t result;
+ const intptr_t kBufferSize = 8 * KB;
+ uint8_t buffer[kBufferSize];
+ while ((result = NO_RETRY_EXPECTED(read(old_fd, buffer, kBufferSize))) >
+ 0) {
+ int wrote = NO_RETRY_EXPECTED(write(new_fd, buffer, result));
+ if (wrote != result) {
+ result = -1;
+ break;
+ }
+ }
+ FDUtils::SaveErrorAndClose(old_fd);
+ FDUtils::SaveErrorAndClose(new_fd);
+ if (result < 0) {
+ int e = errno;
+ VOID_NO_RETRY_EXPECTED(unlink(new_path));
+ errno = e;
+ return false;
+ }
+ return true;
+ } else if (type == kIsDirectory) {
+ errno = EISDIR;
+ } else {
+ errno = ENOENT;
+ }
return false;
}
@@ -353,6 +395,8 @@
const char* File::GetCanonicalPath(const char* pathname) {
+ // TODO(MG-425): realpath() is not implemented.
+#if 0
char* abs_path = NULL;
if (pathname != NULL) {
char* resolved_path = DartUtils::ScopedCString(PATH_MAX + 1);
@@ -364,6 +408,9 @@
ASSERT((abs_path == NULL) || (abs_path == resolved_path));
}
return abs_path;
+#else
+ return pathname;
+#endif
}
diff --git a/runtime/bin/gen_snapshot.cc b/runtime/bin/gen_snapshot.cc
index e18f2f5..05b3842 100644
--- a/runtime/bin/gen_snapshot.cc
+++ b/runtime/bin/gen_snapshot.cc
@@ -1055,7 +1055,7 @@
Dart_Handle result;
// Precompile with specified embedder entry points
- result = Dart_Precompile(standalone_entry_points, true);
+ result = Dart_Precompile(standalone_entry_points, true, NULL, 0);
CHECK_RESULT(result);
// Create a precompiled snapshot.
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index 28804f4..f64e4a8 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -65,6 +65,16 @@
static const char* frontend_filename = NULL;
+// Value of the --save-feedback flag.
+// (This pointer points into an argv buffer and does not need to be
+// free'd.)
+static const char* save_feedback_filename = NULL;
+
+// Value of the --load-feedback flag.
+// (This pointer points into an argv buffer and does not need to be
+// free'd.)
+static const char* load_feedback_filename = NULL;
+
// Value of the --package-root flag.
// (This pointer points into an argv buffer and does not need to be
// free'd.)
@@ -221,6 +231,28 @@
}
+static bool ProcessSaveFeedbackOption(const char* arg,
+ CommandLineOptions* vm_options) {
+ ASSERT(arg != NULL);
+ if (*arg == '-') {
+ return false;
+ }
+ save_feedback_filename = arg;
+ return true;
+}
+
+
+static bool ProcessLoadFeedbackOption(const char* arg,
+ CommandLineOptions* vm_options) {
+ ASSERT(arg != NULL);
+ if (*arg == '-') {
+ return false;
+ }
+ load_feedback_filename = arg;
+ return true;
+}
+
+
static void* GetHashmapKeyFromString(char* key) {
return reinterpret_cast<void*>(key);
}
@@ -564,6 +596,8 @@
{"--snapshot=", ProcessSnapshotFilenameOption},
{"--snapshot-kind=", ProcessSnapshotKindOption},
{"--use-blobs", ProcessUseBlobsOption},
+ {"--save-feedback=", ProcessSaveFeedbackOption},
+ {"--load-feedback=", ProcessLoadFeedbackOption},
{"--trace-loading", ProcessTraceLoadingOption},
{"--hot-reload-test-mode", ProcessHotReloadTestModeOption},
{"--hot-reload-rollback-test-mode", ProcessHotReloadRollbackTestModeOption},
@@ -1297,8 +1331,10 @@
Platform::Exit(kErrorExitCode);
}
- *vmisolate_buffer = reinterpret_cast<const uint8_t*>(read_only_buffer) +
- (vmisolate_position - vmisolate_position);
+ if (vmisolate_size != 0) {
+ *vmisolate_buffer = reinterpret_cast<const uint8_t*>(read_only_buffer) +
+ (vmisolate_position - vmisolate_position);
+ }
*isolate_buffer = reinterpret_cast<const uint8_t*>(read_only_buffer) +
(isolate_position - vmisolate_position);
if (rodata_size == 0) {
@@ -1497,7 +1533,7 @@
#if defined(TARGET_ARCH_X64)
-static void GeneratePrecompiledJITSnapshot() {
+static void GenerateAppJITSnapshot() {
uint8_t* vm_isolate_buffer = NULL;
intptr_t vm_isolate_size = 0;
uint8_t* isolate_buffer = NULL;
@@ -1507,9 +1543,8 @@
uint8_t* rodata_blob_buffer = NULL;
intptr_t rodata_blob_size = 0;
Dart_Handle result = Dart_CreateAppJITSnapshot(
- &vm_isolate_buffer, &vm_isolate_size, &isolate_buffer, &isolate_size,
- &instructions_blob_buffer, &instructions_blob_size, &rodata_blob_buffer,
- &rodata_blob_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));
}
@@ -1528,7 +1563,7 @@
if (Dart_IsError(result)) {
ErrorExit(kErrorExitCode, "%s\n", Dart_GetError(result));
}
- GeneratePrecompiledJITSnapshot();
+ GenerateAppJITSnapshot();
#else
// Create an application snapshot of the script.
uint8_t* vm_isolate_buffer = NULL;
@@ -1687,8 +1722,27 @@
{NULL, NULL, NULL} // Must be terminated with NULL entries.
};
+ uint8_t* feedback_buffer = NULL;
+ intptr_t feedback_length = 0;
+ if (load_feedback_filename != NULL) {
+ File* file = File::Open(load_feedback_filename, File::kRead);
+ if (file == NULL) {
+ ErrorExit(kErrorExitCode, "Failed to read JIT feedback.\n");
+ }
+ feedback_length = file->Length();
+ feedback_buffer = reinterpret_cast<uint8_t*>(malloc(feedback_length));
+ if (!file->ReadFully(feedback_buffer, feedback_length)) {
+ ErrorExit(kErrorExitCode, "Failed to read JIT feedback.\n");
+ }
+ file->Release();
+ }
+
const bool reset_fields = gen_snapshot_kind == kAppAOT;
- result = Dart_Precompile(standalone_entry_points, reset_fields);
+ result = Dart_Precompile(standalone_entry_points, reset_fields,
+ feedback_buffer, feedback_length);
+ if (feedback_buffer != NULL) {
+ free(feedback_buffer);
+ }
CHECK_RESULT(result);
}
@@ -1732,6 +1786,16 @@
}
}
CHECK_RESULT(result);
+
+ if (save_feedback_filename != NULL) {
+ uint8_t* buffer = NULL;
+ intptr_t size = 0;
+ result = Dart_SaveJITFeedback(&buffer, &size);
+ if (Dart_IsError(result)) {
+ ErrorExit(kErrorExitCode, "%s\n", Dart_GetError(result));
+ }
+ WriteSnapshotFile(save_feedback_filename, false, buffer, size);
+ }
}
}
diff --git a/runtime/bin/platform_fuchsia.cc b/runtime/bin/platform_fuchsia.cc
index caa5aef..53f07ac 100644
--- a/runtime/bin/platform_fuchsia.cc
+++ b/runtime/bin/platform_fuchsia.cc
@@ -10,6 +10,7 @@
#include <string.h> // NOLINT
#include <unistd.h> // NOLINT
+#include "bin/dartutils.h"
#include "bin/fdutils.h"
#include "bin/file.h"
@@ -52,15 +53,59 @@
char** Platform::Environment(intptr_t* count) {
- char** result =
- reinterpret_cast<char**>(Dart_ScopeAllocate(1 * sizeof(*result)));
- result[0] = NULL;
+ // Using environ directly is only safe as long as we do not
+ // provide access to modifying environment variables.
+ intptr_t i = 0;
+ char** tmp = environ;
+ while (*(tmp++) != NULL) {
+ i++;
+ }
+ *count = i;
+ char** result;
+ result = reinterpret_cast<char**>(Dart_ScopeAllocate(i * sizeof(*result)));
+ for (intptr_t current = 0; current < i; current++) {
+ result[current] = environ[current];
+ }
return result;
}
const char* Platform::ResolveExecutablePath() {
- return "dart";
+ // The string used on the command line to spawn the executable is in argv_[0].
+ // If that string is a relative or absolute path, i.e. it contains a '/', then
+ // we make the path absolute if it is not already and return it. If argv_[0]
+ // does not contain a '/', we assume it is a program whose location is
+ // resolved via the PATH environment variable, and search for it using the
+ // paths found there.
+ const char* path = getenv("PATH");
+ if ((strchr(argv_[0], '/') != NULL) || (path == NULL)) {
+ if (argv_[0][0] == '/') {
+ return File::GetCanonicalPath(argv_[0]);
+ } else {
+ char* result = DartUtils::ScopedCString(PATH_MAX + 1);
+ char* cwd = DartUtils::ScopedCString(PATH_MAX + 1);
+ getcwd(cwd, PATH_MAX);
+ snprintf(result, PATH_MAX, "%s/%s", cwd, argv_[0]);
+ result[PATH_MAX] = '\0';
+ ASSERT(File::Exists(result));
+ return File::GetCanonicalPath(result);
+ }
+ } else {
+ char* pathcopy = DartUtils::ScopedCopyCString(path);
+ char* result = DartUtils::ScopedCString(PATH_MAX + 1);
+ char* save = NULL;
+ while ((pathcopy = strtok_r(pathcopy, ":", &save)) != NULL) {
+ snprintf(result, PATH_MAX, "%s/%s", pathcopy, argv_[0]);
+ result[PATH_MAX] = '\0';
+ if (File::Exists(result)) {
+ return File::GetCanonicalPath(result);
+ }
+ pathcopy = NULL;
+ }
+ // Couldn't find it. This causes null to be returned for
+ // Platform.resovledExecutable.
+ return NULL;
+ }
}
diff --git a/runtime/bin/process_fuchsia.cc b/runtime/bin/process_fuchsia.cc
index 2bcef56..9eb4d74 100644
--- a/runtime/bin/process_fuchsia.cc
+++ b/runtime/bin/process_fuchsia.cc
@@ -22,6 +22,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/epoll.h>
#include <unistd.h>
#include "bin/dartutils.h"
@@ -29,6 +30,7 @@
#include "bin/lockers.h"
#include "bin/log.h"
#include "platform/signal_blocker.h"
+#include "platform/utils.h"
// #define PROCESS_LOGGING 1
#if defined(PROCESS_LOGGING)
@@ -425,19 +427,164 @@
}
+static bool ProcessWaitCleanup(intptr_t out,
+ intptr_t err,
+ intptr_t exit_event,
+ intptr_t epoll_fd) {
+ int e = errno;
+ VOID_NO_RETRY_EXPECTED(close(out));
+ VOID_NO_RETRY_EXPECTED(close(err));
+ VOID_NO_RETRY_EXPECTED(close(exit_event));
+ VOID_NO_RETRY_EXPECTED(close(epoll_fd));
+ errno = e;
+ return false;
+}
+
+
+class BufferList : public BufferListBase {
+ public:
+ BufferList() {}
+
+ bool Read(int fd, intptr_t available) {
+ // Read all available bytes.
+ while (available > 0) {
+ if (free_size_ == 0) {
+ Allocate();
+ }
+ ASSERT(free_size_ > 0);
+ ASSERT(free_size_ <= kBufferSize);
+ intptr_t block_size = dart::Utils::Minimum(free_size_, available);
+ intptr_t bytes = NO_RETRY_EXPECTED(
+ read(fd, reinterpret_cast<void*>(FreeSpaceAddress()), block_size));
+ if (bytes < 0) {
+ return false;
+ }
+ data_size_ += bytes;
+ free_size_ -= bytes;
+ available -= bytes;
+ }
+ return true;
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(BufferList);
+};
+
+
bool Process::Wait(intptr_t pid,
intptr_t in,
intptr_t out,
intptr_t err,
intptr_t exit_event,
ProcessResult* result) {
- UNIMPLEMENTED();
- return false;
+ VOID_NO_RETRY_EXPECTED(close(in));
+
+ // There is no return from this function using Dart_PropagateError
+ // as memory used by the buffer lists is freed through their
+ // destructors.
+ BufferList out_data;
+ BufferList err_data;
+ union {
+ uint8_t bytes[8];
+ int32_t ints[2];
+ } exit_code_data;
+
+ // The initial size passed to epoll_create is ignore on newer (>=
+ // 2.6.8) Linux versions
+ static const int kEpollInitialSize = 64;
+ int epoll_fd = NO_RETRY_EXPECTED(epoll_create(kEpollInitialSize));
+ if (epoll_fd == -1) {
+ return ProcessWaitCleanup(out, err, exit_event, epoll_fd);
+ }
+ if (!FDUtils::SetCloseOnExec(epoll_fd)) {
+ return ProcessWaitCleanup(out, err, exit_event, epoll_fd);
+ }
+
+ struct epoll_event event;
+ event.events = EPOLLRDHUP | EPOLLIN;
+ event.data.fd = out;
+ int status = NO_RETRY_EXPECTED(
+ epoll_ctl(epoll_fd, EPOLL_CTL_ADD, out, &event));
+ if (status == -1) {
+ return ProcessWaitCleanup(out, err, exit_event, epoll_fd);
+ }
+ event.data.fd = err;
+ status = NO_RETRY_EXPECTED(
+ epoll_ctl(epoll_fd, EPOLL_CTL_ADD, err, &event));
+ if (status == -1) {
+ return ProcessWaitCleanup(out, err, exit_event, epoll_fd);
+ }
+ event.data.fd = exit_event;
+ status = NO_RETRY_EXPECTED(
+ epoll_ctl(epoll_fd, EPOLL_CTL_ADD, exit_event, &event));
+ if (status == -1) {
+ return ProcessWaitCleanup(out, err, exit_event, epoll_fd);
+ }
+ intptr_t active = 3;
+
+ static const intptr_t kMaxEvents = 16;
+ struct epoll_event events[kMaxEvents];
+ while (active > 0) {
+ // TODO(US-109): When the epoll implementation is properly edge-triggered,
+ // remove this sleep, which prevents the message queue from being
+ // overwhelmed and leading to memory exhaustion.
+ usleep(5000);
+ intptr_t result = NO_RETRY_EXPECTED(
+ epoll_wait(epoll_fd, events, kMaxEvents, -1));
+ if ((result < 0) && (errno != EWOULDBLOCK)) {
+ return ProcessWaitCleanup(out, err, exit_event, epoll_fd);
+ }
+ for (intptr_t i = 0; i < result; i++) {
+ if ((events[i].events & EPOLLIN) != 0) {
+ const intptr_t avail = FDUtils::AvailableBytes(events[i].data.fd);
+ if (events[i].data.fd == out) {
+ if (!out_data.Read(out, avail)) {
+ return ProcessWaitCleanup(out, err, exit_event, epoll_fd);
+ }
+ } else if (events[i].data.fd == err) {
+ if (!err_data.Read(err, avail)) {
+ return ProcessWaitCleanup(out, err, exit_event, epoll_fd);
+ }
+ } else if (events[i].data.fd == exit_event) {
+ if (avail == 8) {
+ intptr_t b =
+ NO_RETRY_EXPECTED(read(exit_event, exit_code_data.bytes, 8));
+ if (b != 8) {
+ return ProcessWaitCleanup(out, err, exit_event, epoll_fd);
+ }
+ }
+ } else {
+ UNREACHABLE();
+ }
+ }
+ if ((events[i].events & (EPOLLHUP | EPOLLRDHUP)) != 0) {
+ NO_RETRY_EXPECTED(close(events[i].data.fd));
+ active--;
+ VOID_NO_RETRY_EXPECTED(
+ epoll_ctl(epoll_fd, EPOLL_CTL_DEL, events[i].data.fd, NULL));
+ }
+ }
+ }
+ VOID_NO_RETRY_EXPECTED(close(epoll_fd));
+
+ // All handles closed and all data read.
+ result->set_stdout_data(out_data.GetData());
+ result->set_stderr_data(err_data.GetData());
+
+ // Calculate the exit code.
+ intptr_t exit_code = exit_code_data.ints[0];
+ intptr_t negative = exit_code_data.ints[1];
+ if (negative != 0) {
+ exit_code = -exit_code;
+ }
+ result->set_exit_code(exit_code);
+
+ return true;
}
bool Process::Kill(intptr_t id, int signal) {
- UNIMPLEMENTED();
+ errno = ENOSYS;
return false;
}
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index e1092cc..800b837 100644
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -1034,27 +1034,6 @@
intptr_t* size);
/**
- * Creates a snapshot of the specified library loaded in the isolate.
- *
- * A library snapshot can be used for implementing fast startup of applications
- * (skips tokenizing and parsing process). A Snapshot of the library
- * can only be created before any dart code has executed.
- *
- * Requires there to be a current isolate which already has loaded the library.
- *
- * \param library A library for which the snapshot needs to be created.
- * \param buffer Returns a pointer to a buffer containing
- * the snapshot. This buffer is scope allocated and is only valid
- * until the next call to Dart_ExitScope.
- * \param size Returns the size of the buffer.
- *
- * \return A valid handle if no error occurs during the operation.
- */
-DART_EXPORT Dart_Handle Dart_CreateLibrarySnapshot(Dart_Handle library,
- uint8_t** buffer,
- intptr_t* size);
-
-/**
* Schedules an interrupt for the specified isolate.
*
* When the isolate is interrupted, the isolate interrupt callback
@@ -3185,6 +3164,22 @@
* ==============
*/
+/**
+ * Saves a serialized version of the information collected for use by the
+ * optimizing compiler, such as type feedback and usage counters. When this
+ * information is passed to Dart_Precompile, the AOT compiler may use it to
+ * produce faster and smaller code. The feedback is only used if the JIT that
+ * created it and the AOT compiler consuming it
+ * - are running the same Dart program
+ * - are built from the same version of the VM
+ * - agree on whether type checks and assertions are enabled
+ *
+ * \return Returns an error handler if the VM was built in a mode that does not
+ * support saving JIT feedback.
+ */
+DART_EXPORT Dart_Handle Dart_SaveJITFeedback(uint8_t** buffer,
+ intptr_t* buffer_length);
+
typedef struct {
const char* library_uri;
@@ -3214,7 +3209,10 @@
* constructors was encountered.
*/
DART_EXPORT Dart_Handle
-Dart_Precompile(Dart_QualifiedFunctionName entry_points[], bool reset_fields);
+Dart_Precompile(Dart_QualifiedFunctionName entry_points[],
+ bool reset_fields,
+ uint8_t* jit_feedback,
+ intptr_t jit_feedback_length);
/**
@@ -3285,9 +3283,7 @@
* \return A valid handle if no error occurs during the operation.
*/
DART_EXPORT Dart_Handle
-Dart_CreateAppJITSnapshot(uint8_t** vm_isolate_snapshot_buffer,
- intptr_t* vm_isolate_snapshot_size,
- uint8_t** isolate_snapshot_buffer,
+Dart_CreateAppJITSnapshot(uint8_t** isolate_snapshot_buffer,
intptr_t* isolate_snapshot_size,
uint8_t** instructions_blob_buffer,
intptr_t* instructions_blob_size,
diff --git a/runtime/observatory/lib/models.dart b/runtime/observatory/lib/models.dart
index a196975..71619ca 100644
--- a/runtime/observatory/lib/models.dart
+++ b/runtime/observatory/lib/models.dart
@@ -45,11 +45,13 @@
part 'src/models/objects/sentinel.dart';
part 'src/models/objects/source_location.dart';
part 'src/models/objects/target.dart';
+part 'src/models/objects/thread.dart';
part 'src/models/objects/token_stream.dart';
part 'src/models/objects/timeline_event.dart';
part 'src/models/objects/type_arguments.dart';
part 'src/models/objects/unknown.dart';
part 'src/models/objects/vm.dart';
+part 'src/models/objects/zone.dart';
part 'src/models/repositories/allocation_profile.dart';
part 'src/models/repositories/breakpoint.dart';
diff --git a/runtime/observatory/lib/src/models/objects/isolate.dart b/runtime/observatory/lib/src/models/objects/isolate.dart
index f114941..8cc5c79 100644
--- a/runtime/observatory/lib/src/models/objects/isolate.dart
+++ b/runtime/observatory/lib/src/models/objects/isolate.dart
@@ -51,6 +51,9 @@
/// [optional] The error that is causing this isolate to exit, if applicable.
Error get error;
+ /// The list of threads associated with this isolate.
+ Iterable<Thread> get threads;
+
/// The current pause on exception mode for this isolate.
//ExceptionPauseMode get exceptionPauseMode;
diff --git a/runtime/observatory/lib/src/models/objects/thread.dart b/runtime/observatory/lib/src/models/objects/thread.dart
new file mode 100644
index 0000000..a62353f
--- /dev/null
+++ b/runtime/observatory/lib/src/models/objects/thread.dart
@@ -0,0 +1,25 @@
+// 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.
+
+part of models;
+
+enum ThreadKind {
+ unknownTask,
+ mutatorTask,
+ compilerTask,
+ sweeperTask,
+ markerTask,
+ finalizerTask
+}
+
+abstract class Thread {
+ /// The id associated with the thread on creation.
+ String get id;
+
+ /// The task type associated with the thread.
+ ThreadKind get kind;
+
+ /// A list of all the zones held by the thread.
+ Iterable<Zone> get zones;
+}
diff --git a/runtime/observatory/lib/src/models/objects/zone.dart b/runtime/observatory/lib/src/models/objects/zone.dart
new file mode 100644
index 0000000..51840cb
--- /dev/null
+++ b/runtime/observatory/lib/src/models/objects/zone.dart
@@ -0,0 +1,14 @@
+// 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.
+
+part of models;
+
+abstract class Zone {
+ /// The total amount of memory in bytes allocated in the zone, including
+ /// memory that is not actually being used.
+ int get capacity;
+
+ /// The total amount of memory in bytes actually used in the zone.
+ int get used;
+}
diff --git a/runtime/observatory/lib/src/service/object.dart b/runtime/observatory/lib/src/service/object.dart
index 58ef53f..3611ef8 100644
--- a/runtime/observatory/lib/src/service/object.dart
+++ b/runtime/observatory/lib/src/service/object.dart
@@ -238,6 +238,9 @@
case 'SourceLocation':
obj = new SourceLocation._empty(owner);
break;
+ case '_Thread':
+ obj = new Thread._empty(owner);
+ break;
case 'UnresolvedSourceLocation':
obj = new UnresolvedSourceLocation._empty(owner);
break;
@@ -1501,6 +1504,9 @@
List<ByteData> _chunksInProgress;
+ List<Thread> get threads => _threads;
+ final List<Thread> _threads = new List<Thread>();
+
void _loadHeapSnapshot(ServiceEvent event) {
if (_snapshotFetch == null || _snapshotFetch.isClosed) {
// No outstanding snapshot request. Presumably another client asked for a
@@ -1624,6 +1630,11 @@
if (map['extensionRPCs'] != null) {
extensionRPCs.addAll(map['extensionRPCs']);
}
+
+ threads.clear();
+ if(map['threads'] != null) {
+ threads.addAll(map['threads']);
+ }
}
Future<TagProfile> updateTagProfile() {
@@ -3056,6 +3067,58 @@
String get shortName => valueAsString;
}
+class Thread extends ServiceObject implements M.Thread {
+ M.ThreadKind get kind => _kind;
+ M.ThreadKind _kind;
+ List<Zone> get zones => _zones;
+ final List<Zone> _zones = new List<Zone>();
+
+ Thread._empty(ServiceObjectOwner owner) : super._empty(owner);
+
+ void _update(Map map, bool mapIsRef) {
+ String kindString = map['kind'];
+ List<Map> zoneList = map['zones'];
+
+ switch(kindString) {
+ case "kUnknownTask":
+ _kind = M.ThreadKind.unknownTask;
+ break;
+ case "kMutatorTask":
+ _kind = M.ThreadKind.mutatorTask;
+ break;
+ case "kCompilerTask":
+ _kind = M.ThreadKind.compilerTask;
+ break;
+ case "kSweeperTask":
+ _kind = M.ThreadKind.sweeperTask;
+ break;
+ case "kMarkerTask":
+ _kind = M.ThreadKind.markerTask;
+ break;
+ case "kFinalizerTask":
+ _kind = M.ThreadKind.finalizerTask;
+ break;
+ default:
+ assert(false);
+ }
+ zones.clear();
+ zoneList.forEach((zone) {
+ int capacity = zone['capacity'];
+ int used = zone['used'];
+ zones.add(new Zone(capacity, used));
+ });
+ }
+}
+
+class Zone implements M.Zone {
+ int get capacity => _capacity;
+ int _capacity;
+ int get used => _used;
+ int _used;
+
+ Zone(this._capacity, this._used);
+}
+
class Field extends HeapObject implements M.Field {
// Library or Class.
HeapObject dartOwner;
diff --git a/runtime/observatory/observatory_sources.gypi b/runtime/observatory/observatory_sources.gypi
index c139cd3..a83a34c 100644
--- a/runtime/observatory/observatory_sources.gypi
+++ b/runtime/observatory/observatory_sources.gypi
@@ -173,11 +173,13 @@
'lib/src/models/objects/sentinel.dart',
'lib/src/models/objects/source_location.dart',
'lib/src/models/objects/target.dart',
+ 'lib/src/models/objects/thread.dart',
'lib/src/models/objects/timeline_event.dart',
'lib/src/models/objects/token_stream.dart',
'lib/src/models/objects/type_arguments.dart',
'lib/src/models/objects/unknown.dart',
'lib/src/models/objects/vm.dart',
+ 'lib/src/models/objects/zone.dart',
'lib/src/models/repositories/allocation_profile.dart',
'lib/src/models/repositories/breakpoint.dart',
'lib/src/models/repositories/class.dart',
diff --git a/runtime/observatory/tests/service/get_zone_memory_info_rpc_test.dart b/runtime/observatory/tests/service/get_zone_memory_info_rpc_test.dart
new file mode 100644
index 0000000..7d5f004
--- /dev/null
+++ b/runtime/observatory/tests/service/get_zone_memory_info_rpc_test.dart
@@ -0,0 +1,38 @@
+// 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.
+// VMOptions=--error_on_bad_type --error_on_bad_override
+
+import 'package:observatory/service_io.dart';
+import 'package:unittest/unittest.dart';
+
+import 'test_helper.dart';
+
+var tests = [
+ (VM vm) async {
+ isInstanceOf<int> isInt = new isInstanceOf<int>();
+ // Just iterate over all the isolates to confirm they have
+ // the correct fields needed to examine zone memory usage.
+ for (Isolate isolate in vm.isolates) {
+ await isolate.reload();
+
+ expect(isolate.threads, isNotNull);
+ List<Thread> threads = isolate.threads;
+
+ for (Thread thread in threads) {
+ expect(thread.type, equals('_Thread'));
+ expect(thread.id, isNotNull);
+ expect(thread.kind, isNotNull);
+ expect(thread.zones, isNotNull);
+ List<Zone> zones = thread.zones;
+
+ for (Zone zone in zones) {
+ expect(zone.capacity, isInt);
+ expect(zone.used, isInt);
+ }
+ }
+ }
+ },
+];
+
+main(args) async => runVMTests(args, tests);
diff --git a/runtime/tests/vm/dart/hello_fuchsia_test.dart b/runtime/tests/vm/dart/hello_fuchsia_test.dart
index bcda2bf..8053b85 100644
--- a/runtime/tests/vm/dart/hello_fuchsia_test.dart
+++ b/runtime/tests/vm/dart/hello_fuchsia_test.dart
@@ -380,10 +380,21 @@
}
Future testProcess() async {
- Process p = await Process.start(Platform.executable, ["--version"]);
+ String exe = Platform.resolvedExecutable;
+ print("Running $exe --version");
+ Process p = await Process.start(exe, ["--version"]);
p.stderr.transform(UTF8.decoder).listen(print);
int code = await p.exitCode;
- print("dart --version exited with code $code");
+ print("$exe --version exited with code $code");
+}
+
+void testProcessRunSync() {
+ String exe = Platform.resolvedExecutable;
+ print("Running $exe --version");
+ var result = Process.runSync(exe, ["--version"]);
+ print("$exe --version exited with code ${result.exitCode}");
+ print("$exe --version had stdout = '${result.stdout}'");
+ print("$exe --version had stderr = '${result.stderr}'");
}
Future testLs(String path) async {
@@ -393,6 +404,33 @@
}
}
+void testPlatformEnvironment() {
+ Map<String, String> env = Platform.environment;
+ for (String k in env.keys) {
+ String v = env[k];
+ print("$k = '$v'");
+ }
+}
+
+Future testCopy() async {
+ final String sourceName = "foo";
+ final String destName = "bar";
+ Directory tmp = await Directory.systemTemp.createTemp("testCopy");
+ File sourceFile = new File("${tmp.path}/$sourceName");
+ File destFile = new File("${tmp.path}/$destName");
+ List<int> data = new List<int>.generate(10 * 1024, (int i) => i & 0xff);
+ await sourceFile.writeAsBytes(data);
+ await sourceFile.copy(destFile.path);
+ List<int> resultData = await destFile.readAsBytes();
+ assert(data.length == resultData.length);
+ for (int i = 0; i < data.length; i++) {
+ assert(data[i] == resultData[i]);
+ }
+ await sourceFile.delete();
+ await destFile.delete();
+ await tmp.delete();
+}
+
main() async {
print("Hello, Fuchsia!");
@@ -428,9 +466,21 @@
await testLs("/");
print("lsTest done");
+ print("testPlatformEnvironment");
+ testPlatformEnvironment();
+ print("testPlatformEnvironment done");
+
print("testProcess");
await testProcess();
print("testProcess done");
+ print("testProcessRunSync");
+ testProcessRunSync();
+ print("testProcessRunSync done");
+
+ print("testCopy");
+ await testCopy();
+ print("testCopy done");
+
print("Goodbyte, Fuchsia!");
}
diff --git a/runtime/vm/aot_optimizer.cc b/runtime/vm/aot_optimizer.cc
index 0013157..93501ec 100644
--- a/runtime/vm/aot_optimizer.cc
+++ b/runtime/vm/aot_optimizer.cc
@@ -100,32 +100,6 @@
}
-void AotOptimizer::PopulateWithICData() {
- ASSERT(current_iterator_ == NULL);
- for (BlockIterator block_it = flow_graph_->reverse_postorder_iterator();
- !block_it.Done(); block_it.Advance()) {
- ForwardInstructionIterator it(block_it.Current());
- for (; !it.Done(); it.Advance()) {
- Instruction* instr = it.Current();
- if (instr->IsInstanceCall()) {
- InstanceCallInstr* call = instr->AsInstanceCall();
- if (!call->HasICData()) {
- const Array& arguments_descriptor = Array::Handle(
- zone(), ArgumentsDescriptor::New(call->ArgumentCount(),
- call->argument_names()));
- const ICData& ic_data = ICData::ZoneHandle(
- zone(), ICData::New(function(), call->function_name(),
- arguments_descriptor, call->deopt_id(),
- call->checked_argument_count(), false));
- call->set_ic_data(&ic_data);
- }
- }
- }
- current_iterator_ = NULL;
- }
-}
-
-
bool AotOptimizer::RecognizeRuntimeTypeGetter(InstanceCallInstr* call) {
if ((precompiler_ == NULL) || !precompiler_->get_runtime_type_is_unique()) {
return false;
@@ -1550,47 +1524,51 @@
return;
}
- TypeRangeCache* cache = thread()->type_range_cache();
- intptr_t lower_limit, upper_limit;
- if (cache != NULL &&
- cache->InstanceOfHasClassRange(type, &lower_limit, &upper_limit)) {
- // left.instanceof(type) =>
- // _classRangeCheck(left.cid, lower_limit, upper_limit)
+ if (precompiler_ != NULL) {
+ TypeRangeCache* cache = precompiler_->type_range_cache();
+ intptr_t lower_limit, upper_limit;
+ if (cache != NULL &&
+ cache->InstanceOfHasClassRange(type, &lower_limit, &upper_limit)) {
+ // left.instanceof(type) =>
+ // _classRangeCheck(left.cid, lower_limit, upper_limit)
- LoadClassIdInstr* left_cid = new (Z) LoadClassIdInstr(new (Z) Value(left));
- InsertBefore(call, left_cid, NULL, FlowGraph::kValue);
- ConstantInstr* lower_cid =
- flow_graph()->GetConstant(Smi::Handle(Z, Smi::New(lower_limit)));
- ConstantInstr* upper_cid =
- flow_graph()->GetConstant(Smi::Handle(Z, Smi::New(upper_limit)));
+ LoadClassIdInstr* left_cid =
+ new (Z) LoadClassIdInstr(new (Z) Value(left));
+ InsertBefore(call, left_cid, NULL, FlowGraph::kValue);
+ ConstantInstr* lower_cid =
+ flow_graph()->GetConstant(Smi::Handle(Z, Smi::New(lower_limit)));
+ ConstantInstr* upper_cid =
+ flow_graph()->GetConstant(Smi::Handle(Z, Smi::New(upper_limit)));
- ZoneGrowableArray<PushArgumentInstr*>* args =
- new (Z) ZoneGrowableArray<PushArgumentInstr*>(3);
- PushArgumentInstr* arg = new (Z) PushArgumentInstr(new (Z) Value(left_cid));
- InsertBefore(call, arg, NULL, FlowGraph::kEffect);
- args->Add(arg);
- arg = new (Z) PushArgumentInstr(new (Z) Value(lower_cid));
- InsertBefore(call, arg, NULL, FlowGraph::kEffect);
- args->Add(arg);
- arg = new (Z) PushArgumentInstr(new (Z) Value(upper_cid));
- InsertBefore(call, arg, NULL, FlowGraph::kEffect);
- args->Add(arg);
+ ZoneGrowableArray<PushArgumentInstr*>* args =
+ new (Z) ZoneGrowableArray<PushArgumentInstr*>(3);
+ PushArgumentInstr* arg =
+ new (Z) PushArgumentInstr(new (Z) Value(left_cid));
+ InsertBefore(call, arg, NULL, FlowGraph::kEffect);
+ args->Add(arg);
+ arg = new (Z) PushArgumentInstr(new (Z) Value(lower_cid));
+ InsertBefore(call, arg, NULL, FlowGraph::kEffect);
+ args->Add(arg);
+ arg = new (Z) PushArgumentInstr(new (Z) Value(upper_cid));
+ InsertBefore(call, arg, NULL, FlowGraph::kEffect);
+ args->Add(arg);
- const Library& dart_internal =
- Library::Handle(Z, Library::InternalLibrary());
- const String& target_name = negate ? Symbols::_classRangeCheckNegative()
- : Symbols::_classRangeCheck();
- const Function& target = Function::ZoneHandle(
- Z, dart_internal.LookupFunctionAllowPrivate(target_name));
- ASSERT(!target.IsNull());
- ASSERT(target.IsRecognized() && target.always_inline());
+ const Library& dart_internal =
+ Library::Handle(Z, Library::InternalLibrary());
+ const String& target_name = negate ? Symbols::_classRangeCheckNegative()
+ : Symbols::_classRangeCheck();
+ const Function& target = Function::ZoneHandle(
+ Z, dart_internal.LookupFunctionAllowPrivate(target_name));
+ ASSERT(!target.IsNull());
+ ASSERT(target.IsRecognized() && target.always_inline());
- StaticCallInstr* new_call =
- new (Z) StaticCallInstr(call->token_pos(), target,
- Object::null_array(), // argument_names
- args, call->deopt_id());
- ReplaceCall(call, new_call);
- return;
+ StaticCallInstr* new_call =
+ new (Z) StaticCallInstr(call->token_pos(), target,
+ Object::null_array(), // argument_names
+ args, call->deopt_id());
+ ReplaceCall(call, new_call);
+ return;
+ }
}
const ICData& unary_checks =
diff --git a/runtime/vm/aot_optimizer.h b/runtime/vm/aot_optimizer.h
index 16e879e..2b8938d 100644
--- a/runtime/vm/aot_optimizer.h
+++ b/runtime/vm/aot_optimizer.h
@@ -28,10 +28,6 @@
FlowGraph* flow_graph() const { return flow_graph_; }
- // Add ICData to InstanceCalls, so that optimizations can be run on them.
- // TODO(srdjan): StaticCals as well?
- void PopulateWithICData();
-
// Use ICData to optimize, replace or eliminate instructions.
void ApplyICData();
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
index 65a001d..89f3be7 100644
--- a/runtime/vm/clustered_snapshot.cc
+++ b/runtime/vm/clustered_snapshot.cc
@@ -4666,6 +4666,12 @@
}
AddBaseObject(table->At(kDynamicCid));
AddBaseObject(table->At(kVoidCid));
+
+ if (kind_ != Snapshot::kAppAOT) {
+ for (intptr_t i = 0; i < StubCode::NumEntries(); i++) {
+ AddBaseObject(StubCode::EntryAt(i)->code());
+ }
+ }
}
@@ -4679,7 +4685,9 @@
Push(symbols.raw());
Push(scripts.raw());
if (Snapshot::IncludesCode(kind_)) {
- StubCode::Push(this);
+ for (intptr_t i = 0; i < StubCode::NumEntries(); i++) {
+ Push(StubCode::EntryAt(i)->code());
+ }
}
Serialize();
@@ -4688,7 +4696,9 @@
WriteRef(symbols.raw());
WriteRef(scripts.raw());
if (Snapshot::IncludesCode(kind_)) {
- StubCode::WriteRef(this);
+ for (intptr_t i = 0; i < StubCode::NumEntries(); i++) {
+ WriteRef(StubCode::EntryAt(i)->code());
+ }
}
#if defined(DEBUG)
@@ -5050,6 +5060,12 @@
}
AddBaseObject(table->At(kDynamicCid));
AddBaseObject(table->At(kVoidCid));
+
+ if (kind_ != Snapshot::kAppAOT) {
+ for (intptr_t i = 0; i < StubCode::NumEntries(); i++) {
+ AddBaseObject(StubCode::EntryAt(i)->code());
+ }
+ }
}
@@ -5071,7 +5087,11 @@
isolate()->object_store()->set_symbol_table(symbol_table);
ReadRef(); // Script list.
if (Snapshot::IncludesCode(kind_)) {
- StubCode::ReadRef(this);
+ Code& code = Code::Handle(zone_);
+ for (intptr_t i = 0; i < StubCode::NumEntries(); i++) {
+ code ^= ReadRef();
+ StubCode::EntryAtPut(i, new StubEntry(code));
+ }
}
#if defined(DEBUG)
@@ -5316,8 +5336,10 @@
if (Snapshot::IncludesCode(kind_)) {
instructions_writer_->Write(
- *vm_isolate_snapshot_buffer_, vm_isolate_snapshot_size_,
- *isolate_snapshot_buffer_, isolate_snapshot_size_);
+ vm_isolate_snapshot_buffer_ == NULL ? NULL
+ : *vm_isolate_snapshot_buffer_,
+ vm_isolate_snapshot_size_, *isolate_snapshot_buffer_,
+ isolate_snapshot_size_);
if (FLAG_print_snapshot_sizes) {
OS::Print("ReadOnlyData(CodeSize): %" Pd "\n",
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index 568975c..2f9e6d7 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -224,23 +224,21 @@
if (data_snapshot == NULL) {
return strdup("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 strdup("Precompiled runtime requires a precompiled snapshot");
#else
- if (instructions_snapshot != NULL) {
- return strdup("Unexpected instructions snapshot");
- }
- if (data_snapshot != NULL) {
- return strdup("Unexpected rodata snapshot");
- }
StubCode::InitOnce();
#endif
} else {
return strdup("Invalid vm isolate snapshot seen");
}
+ if (instructions_snapshot != NULL) {
+ vm_isolate_->SetupInstructionsSnapshotPage(instructions_snapshot);
+ }
+ if (instructions_snapshot != NULL) {
+ vm_isolate_->SetupDataSnapshotPage(data_snapshot);
+ }
VmIsolateSnapshotReader reader(snapshot->kind(), snapshot->content(),
snapshot->length(), instructions_snapshot,
data_snapshot, T);
@@ -533,7 +531,9 @@
const String& message = String::Handle(String::New("Invalid snapshot"));
return ApiError::New(message);
}
- if (snapshot->kind() != snapshot_kind_) {
+ if (snapshot->kind() != snapshot_kind_ &&
+ !((snapshot->kind() == Snapshot::kAppJIT) &&
+ (snapshot_kind_ == Snapshot::kCore))) {
const String& message = String::Handle(
String::NewFormatted("Invalid snapshot kind: got '%s', expected '%s'",
Snapshot::KindToCString(snapshot->kind()),
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 61daa77..a68cfbf 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -36,6 +36,7 @@
#include "vm/port.h"
#include "vm/precompiler.h"
#include "vm/profiler.h"
+#include "vm/program_visitor.h"
#include "vm/resolver.h"
#include "vm/reusable_handles.h"
#include "vm/service_event.h"
@@ -112,9 +113,9 @@
// An object visitor which will iterate over all the function objects in the
// heap and check if the result type and parameter types are canonicalized
// or not. An assertion is raised if a type is not canonicalized.
-class FunctionVisitor : public ObjectVisitor {
+class CheckFunctionTypesVisitor : public ObjectVisitor {
public:
- explicit FunctionVisitor(Thread* thread)
+ explicit CheckFunctionTypesVisitor(Thread* thread)
: classHandle_(Class::Handle(thread->zone())),
funcHandle_(Function::Handle(thread->zone())),
typeHandle_(AbstractType::Handle(thread->zone())) {}
@@ -1572,7 +1573,7 @@
#if defined(DEBUG)
I->heap()->CollectAllGarbage();
- FunctionVisitor check_canonical(T);
+ CheckFunctionTypesVisitor check_canonical(T);
I->heap()->IterateObjects(&check_canonical);
#endif // #if defined(DEBUG)
@@ -1586,9 +1587,9 @@
}
-static Dart_Handle createLibrarySnapshot(Dart_Handle library,
- uint8_t** buffer,
- intptr_t* size) {
+DART_EXPORT Dart_Handle Dart_CreateScriptSnapshot(uint8_t** buffer,
+ intptr_t* size) {
+ API_TIMELINE_DURATION;
DARTSCOPE(Thread::Current());
Isolate* I = T->isolate();
if (buffer == NULL) {
@@ -1602,16 +1603,11 @@
if (::Dart_IsError(state)) {
return state;
}
- Library& lib = Library::Handle(Z);
- if (library == Dart_Null()) {
- lib ^= I->object_store()->root_library();
- } else {
- lib ^= Api::UnwrapHandle(library);
- }
+ Library& lib = Library::Handle(Z, I->object_store()->root_library());
#if defined(DEBUG)
I->heap()->CollectAllGarbage();
- FunctionVisitor check_canonical(T);
+ CheckFunctionTypesVisitor check_canonical(T);
I->heap()->IterateObjects(&check_canonical);
#endif // #if defined(DEBUG)
@@ -1622,21 +1618,6 @@
}
-DART_EXPORT Dart_Handle Dart_CreateScriptSnapshot(uint8_t** buffer,
- intptr_t* size) {
- API_TIMELINE_DURATION;
- return createLibrarySnapshot(Dart_Null(), buffer, size);
-}
-
-
-DART_EXPORT Dart_Handle Dart_CreateLibrarySnapshot(Dart_Handle library,
- uint8_t** buffer,
- intptr_t* size) {
- API_TIMELINE_DURATION;
- return createLibrarySnapshot(library, buffer, size);
-}
-
-
DART_EXPORT void Dart_InterruptIsolate(Dart_Isolate isolate) {
if (isolate == NULL) {
FATAL1("%s expects argument 'isolate' to be non-null.", CURRENT_FUNC);
@@ -6426,47 +6407,175 @@
}
-// The precompiler is included in dart_bootstrap and dart_noopt, and
-// excluded from dart and dart_precompiled_runtime.
-#if !defined(DART_PRECOMPILER)
+DART_EXPORT
+Dart_Handle Dart_SaveJITFeedback(uint8_t** buffer, intptr_t* buffer_length) {
+#if defined(DART_PRECOMPILED_RUNTIME)
+ return Api::NewError("No JIT feedback to save on an AOT runtime.");
+#elif defined(PRODUCT)
+ // TOOD(rmacnak): We'd need to include the JSON printing code again.
+ return Api::NewError("Dart_SaveJITFeedback not supported in PRODUCT mode.");
+#else
+ Thread* thread = Thread::Current();
+ DARTSCOPE(thread);
+ Isolate* isolate = thread->isolate();
+ Zone* zone = thread->zone();
-DART_EXPORT Dart_Handle
-Dart_Precompile(Dart_QualifiedFunctionName entry_points[], bool reset_fields) {
- return Api::NewError(
- "This VM was built without support for AOT compilation.");
+ if (buffer == NULL) {
+ RETURN_NULL_ERROR(buffer);
+ }
+ if (buffer_length == NULL) {
+ RETURN_NULL_ERROR(buffer_length);
+ }
+
+ JSONStream js_stream;
+ {
+ JSONObject js_profile(&js_stream);
+ js_profile.AddProperty("vmVersion", Version::CommitString());
+ js_profile.AddProperty("asserts", FLAG_enable_asserts);
+ js_profile.AddProperty("typeChecks", FLAG_enable_type_checks);
+
+ {
+ JSONArray js_scripts(&js_profile, "scripts");
+
+ const GrowableObjectArray& libraries = GrowableObjectArray::Handle(
+ zone, isolate->object_store()->libraries());
+ Library& library = Library::Handle(zone);
+ Array& scripts = Array::Handle(zone);
+ Script& script = Script::Handle(zone);
+ String& uri = String::Handle(zone);
+ for (intptr_t i = 0; i < libraries.Length(); i++) {
+ library ^= libraries.At(i);
+ scripts = library.LoadedScripts();
+ for (intptr_t j = 0; j < scripts.Length(); j++) {
+ script ^= scripts.At(j);
+ JSONObject js_script(&js_scripts);
+ uri = script.url();
+ js_script.AddProperty("uri", uri.ToCString());
+ int64_t fp = script.SourceFingerprint();
+ js_script.AddProperty64("checksum", fp);
+ }
+ }
+ }
+
+ {
+ JSONArray js_classes(&js_profile, "classes");
+
+ ClassTable* classes = isolate->class_table();
+ Class& cls = Class::Handle(zone);
+ Library& library = Library::Handle(zone);
+ String& uri = String::Handle(zone);
+ String& name = String::Handle(zone);
+ for (intptr_t cid = kNumPredefinedCids; cid < classes->NumCids(); cid++) {
+ if (!classes->HasValidClassAt(cid)) continue;
+ cls ^= classes->At(cid);
+ library = cls.library();
+ JSONObject js_class(&js_classes);
+ js_class.AddProperty("cid", cid);
+ uri = library.url();
+ js_class.AddProperty("uri", uri.ToCString());
+ name = cls.Name();
+ name = String::RemovePrivateKey(name);
+ js_class.AddProperty("name", name.ToCString());
+ }
+ }
+
+ {
+ JSONArray js_functions(&js_profile, "functions");
+
+ class JITFeedbackFunctionVisitor : public FunctionVisitor {
+ public:
+ JITFeedbackFunctionVisitor(JSONArray* js_functions, Zone* zone)
+ : js_functions_(js_functions),
+ function_(Function::Handle(zone)),
+ owner_(Class::Handle(zone)),
+ name_(String::Handle(zone)),
+ ic_datas_(Array::Handle(zone)),
+ ic_data_(ICData::Handle(zone)),
+ entry_(Object::Handle(zone)) {}
+
+ void Visit(const Function& function) {
+ if (function.usage_counter() == 0) return;
+
+ JSONObject js_function(js_functions_);
+ name_ = function.name();
+ name_ = String::RemovePrivateKey(name_);
+ js_function.AddProperty("name", name_.ToCString());
+ owner_ ^= function.Owner();
+ js_function.AddProperty("class", owner_.id());
+ js_function.AddProperty("tokenPos", function.token_pos().value());
+ js_function.AddProperty("kind",
+ static_cast<intptr_t>(function.kind()));
+ intptr_t usage = function.usage_counter();
+ if (usage < 0) {
+ // Function was in the background compiler's queue.
+ usage = FLAG_optimization_counter_threshold;
+ }
+ js_function.AddProperty("usageCounter", usage);
+
+ ic_datas_ = function.ic_data_array();
+ JSONArray js_icdatas(&js_function, "ics");
+ if (ic_datas_.IsNull()) return;
+
+ for (intptr_t j = 0; j < ic_datas_.Length(); j++) {
+ entry_ = ic_datas_.At(j);
+ if (!entry_.IsICData()) continue; // Skip edge counters.
+ ic_data_ ^= entry_.raw();
+
+ JSONObject js_icdata(&js_icdatas);
+ js_icdata.AddProperty("deoptId", ic_data_.deopt_id());
+ name_ = ic_data_.target_name();
+ name_ = String::RemovePrivateKey(name_);
+ js_icdata.AddProperty("selector", name_.ToCString());
+ js_icdata.AddProperty("isStaticCall", ic_data_.is_static_call());
+ intptr_t num_args_checked = ic_data_.NumArgsTested();
+ js_icdata.AddProperty("argsTested", num_args_checked);
+ JSONArray js_entries(&js_icdata, "entries");
+ for (intptr_t check = 0; check < ic_data_.NumberOfChecks();
+ check++) {
+ GrowableArray<intptr_t> class_ids(num_args_checked);
+ ic_data_.GetClassIdsAt(check, &class_ids);
+ for (intptr_t k = 0; k < num_args_checked; k++) {
+ ASSERT(class_ids[k] != kIllegalCid);
+ js_entries.AddValue(class_ids[k]);
+ }
+ js_entries.AddValue(ic_data_.GetCountAt(check));
+ }
+ }
+ }
+
+ private:
+ JSONArray* js_functions_;
+ Function& function_;
+ Class& owner_;
+ String& name_;
+ Array& ic_datas_;
+ ICData& ic_data_;
+ Object& entry_;
+ };
+
+ JITFeedbackFunctionVisitor visitor(&js_functions, zone);
+ ProgramVisitor::VisitFunctions(&visitor);
+ }
+ }
+
+ js_stream.Steal(reinterpret_cast<char**>(buffer), buffer_length);
+ return Api::Success();
+#endif
}
DART_EXPORT Dart_Handle
-Dart_CreatePrecompiledSnapshotAssembly(uint8_t** assembly_buffer,
- intptr_t* assembly_size) {
- return Api::NewError(
- "This VM was built without support for AOT compilation.");
- return 0;
-}
-
-
-DART_EXPORT Dart_Handle
-Dart_CreatePrecompiledSnapshotBlob(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) {
- return Api::NewError(
- "This VM was built without support for AOT compilation.");
-}
-
-#else // DART_PRECOMPILER
-
-DART_EXPORT Dart_Handle
-Dart_Precompile(Dart_QualifiedFunctionName entry_points[], bool reset_fields) {
+Dart_Precompile(Dart_QualifiedFunctionName entry_points[],
+ bool reset_fields,
+ uint8_t* jit_feedback,
+ intptr_t jit_feedback_length) {
#if defined(TARGET_ARCH_IA32)
- return Api::NewError("Precompilation is not supported on IA32.");
+ return Api::NewError("AOT compilation is not supported on IA32.");
#elif defined(TARGET_ARCH_DBC)
- return Api::NewError("Precompilation is not supported on DBC.");
+ return Api::NewError("AOT compilation is not supported on DBC.");
+#elif !defined(DART_PRECOMPILER)
+ return Api::NewError(
+ "This VM was built without support for AOT compilation.");
#else
API_TIMELINE_BEGIN_END;
DARTSCOPE(Thread::Current());
@@ -6478,8 +6587,8 @@
return result;
}
CHECK_CALLBACK_STATE(T);
- const Error& error =
- Error::Handle(Precompiler::CompileAll(entry_points, reset_fields));
+ const Error& error = Error::Handle(Precompiler::CompileAll(
+ entry_points, reset_fields, jit_feedback, jit_feedback_length));
if (!error.IsNull()) {
return Api::NewHandle(T, error.raw());
}
@@ -6492,9 +6601,12 @@
Dart_CreatePrecompiledSnapshotAssembly(uint8_t** assembly_buffer,
intptr_t* assembly_size) {
#if defined(TARGET_ARCH_IA32)
- return Api::NewError("Precompilation is not supported on IA32.");
+ return Api::NewError("AOT compilation is not supported on IA32.");
#elif defined(TARGET_ARCH_DBC)
- return Api::NewError("Precompilation is not supported on DBC.");
+ return Api::NewError("AOT compilation is not supported on DBC.");
+#elif !defined(DART_PRECOMPILER)
+ return Api::NewError(
+ "This VM was built without support for AOT compilation.");
#else
API_TIMELINE_DURATION;
DARTSCOPE(Thread::Current());
@@ -6540,9 +6652,12 @@
uint8_t** rodata_blob_buffer,
intptr_t* rodata_blob_size) {
#if defined(TARGET_ARCH_IA32)
- return Api::NewError("Precompilation is not supported on IA32.");
+ return Api::NewError("AOT compilation is not supported on IA32.");
#elif defined(TARGET_ARCH_DBC)
- return Api::NewError("Precompilation is not supported on DBC.");
+ return Api::NewError("AOT compilation is not supported on DBC.");
+#elif !defined(DART_PRECOMPILER)
+ return Api::NewError(
+ "This VM was built without support for AOT compilation.");
#else
API_TIMELINE_DURATION;
DARTSCOPE(Thread::Current());
@@ -6596,7 +6711,6 @@
return Api::Success();
#endif
}
-#endif // DART_PRECOMPILER
DART_EXPORT Dart_Handle Dart_PrecompileJIT() {
@@ -6632,9 +6746,7 @@
DART_EXPORT Dart_Handle
-Dart_CreateAppJITSnapshot(uint8_t** vm_isolate_snapshot_buffer,
- intptr_t* vm_isolate_snapshot_size,
- uint8_t** isolate_snapshot_buffer,
+Dart_CreateAppJITSnapshot(uint8_t** isolate_snapshot_buffer,
intptr_t* isolate_snapshot_size,
uint8_t** instructions_blob_buffer,
intptr_t* instructions_blob_size,
@@ -6652,12 +6764,6 @@
return Api::NewError(
"Creating full snapshots requires --load_deferred_eagerly");
}
- 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);
}
@@ -6688,11 +6794,9 @@
BlobInstructionsWriter instructions_writer(instructions_blob_buffer,
rodata_blob_buffer, ApiReallocate,
2 * MB /* initial_size */);
- FullSnapshotWriter writer(Snapshot::kAppJIT, vm_isolate_snapshot_buffer,
- isolate_snapshot_buffer, ApiReallocate,
- &instructions_writer);
+ FullSnapshotWriter writer(Snapshot::kAppJIT, NULL, 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();
diff --git a/runtime/vm/deopt_instructions.cc b/runtime/vm/deopt_instructions.cc
index 31f08cd..345db49 100644
--- a/runtime/vm/deopt_instructions.cc
+++ b/runtime/vm/deopt_instructions.cc
@@ -1077,7 +1077,13 @@
deopt_instr = new (zone()) DeoptMaterializedObjectRefInstr(index);
} else {
ASSERT(!source_loc.IsInvalid());
- switch (value->definition()->representation()) {
+#if defined(TARGET_ARCH_DBC)
+ Representation rep =
+ (value == NULL) ? kTagged : value->definition()->representation();
+#else
+ Representation rep = value->definition()->representation();
+#endif
+ switch (rep) {
case kTagged:
deopt_instr =
new (zone()) DeoptWordInstr(ToCpuRegisterSource(source_loc));
diff --git a/runtime/vm/flow_graph_compiler.cc b/runtime/vm/flow_graph_compiler.cc
index 6d103b8..d0a2cb1 100644
--- a/runtime/vm/flow_graph_compiler.cc
+++ b/runtime/vm/flow_graph_compiler.cc
@@ -67,14 +67,6 @@
DECLARE_FLAG(int, stacktrace_every);
DECLARE_FLAG(charp, stacktrace_filter);
DECLARE_FLAG(bool, trace_compiler);
-DECLARE_FLAG(int, inlining_hotness);
-DECLARE_FLAG(int, inlining_size_threshold);
-DECLARE_FLAG(int, inlining_callee_size_threshold);
-DECLARE_FLAG(int, inline_getters_setters_smaller_than);
-DECLARE_FLAG(int, inlining_depth_threshold);
-DECLARE_FLAG(int, inlining_caller_size_threshold);
-DECLARE_FLAG(int, inlining_constant_arguments_max_size_threshold);
-DECLARE_FLAG(int, inlining_constant_arguments_min_size_threshold);
DECLARE_FLAG(int, reload_every);
DECLARE_FLAG(bool, unbox_numeric_fields);
@@ -84,22 +76,6 @@
FATAL("Precompilation not supported on IA32");
#endif
-#if !defined(DART_PRECOMPILED_RUNTIME)
- // Flags affecting compilation only:
- // There is no counter feedback in precompilation, so ignore the counter
- // when making inlining decisions.
- FLAG_inlining_hotness = 0;
- // Use smaller thresholds in precompilation as we are compiling everything
- // with the optimizing compiler instead of only hot functions.
- FLAG_inlining_size_threshold = 5;
- FLAG_inline_getters_setters_smaller_than = 5;
- FLAG_inlining_callee_size_threshold = 20;
- FLAG_inlining_depth_threshold = 4;
- FLAG_inlining_caller_size_threshold = 1000;
- FLAG_inlining_constant_arguments_max_size_threshold = 100;
- FLAG_inlining_constant_arguments_min_size_threshold = 30;
-#endif
-
FLAG_background_compilation = false;
FLAG_fields_may_be_reset = true;
FLAG_interpret_irregexp = true;
@@ -815,7 +791,7 @@
}
-void FlowGraphCompiler::AddDeoptIndexAtCall(intptr_t deopt_id) {
+CompilerDeoptInfo* FlowGraphCompiler::AddDeoptIndexAtCall(intptr_t deopt_id) {
ASSERT(is_optimizing());
ASSERT(!intrinsic_mode());
CompilerDeoptInfo* info =
@@ -824,6 +800,7 @@
pending_deoptimization_env_);
info->set_pc_offset(assembler()->CodeSize());
deopt_infos_.Add(info);
+ return info;
}
diff --git a/runtime/vm/flow_graph_compiler.h b/runtime/vm/flow_graph_compiler.h
index e8b013f..8d8606b 100644
--- a/runtime/vm/flow_graph_compiler.h
+++ b/runtime/vm/flow_graph_compiler.h
@@ -122,6 +122,9 @@
deopt_id_(deopt_id),
reason_(reason),
flags_(flags),
+#if defined(TARGET_ARCH_DBC)
+ lazy_deopt_with_result_(false),
+#endif
deopt_env_(deopt_env) {
ASSERT(deopt_env != NULL);
}
@@ -143,6 +146,18 @@
uint32_t flags() const { return flags_; }
const Environment* deopt_env() const { return deopt_env_; }
+#if defined(TARGET_ARCH_DBC)
+ // On DBC calls return results on the stack but not all calls have a result.
+ // This needs to be taken into account when constructing lazy deoptimization
+ // environment.
+ // For calls with results we add a deopt instruction that would copy top
+ // of the stack from optimized frame to unoptimized frame effectively
+ // preserving the result of the call.
+ // For calls with no results we don't emit such instruction - because there
+ // is no result pushed by the return sequence.
+ void mark_lazy_deopt_with_result() { lazy_deopt_with_result_ = true; }
+#endif
+
private:
void EmitMaterializations(Environment* env, DeoptInfoBuilder* builder);
@@ -153,6 +168,9 @@
const intptr_t deopt_id_;
const ICData::DeoptReasonId reason_;
const uint32_t flags_;
+#if defined(TARGET_ARCH_DBC)
+ bool lazy_deopt_with_result_;
+#endif
Environment* deopt_env_;
DISALLOW_COPY_AND_ASSIGN(CompilerDeoptInfo);
@@ -499,7 +517,7 @@
uint16_t ToEmbeddableCid(intptr_t cid, Instruction* instruction);
#endif // defined(TARGET_ARCH_DBC)
- void AddDeoptIndexAtCall(intptr_t deopt_id);
+ CompilerDeoptInfo* AddDeoptIndexAtCall(intptr_t deopt_id);
void AddSlowPathCode(SlowPathCode* slow_path);
@@ -583,11 +601,16 @@
bool EndCodeSourceRange(TokenPosition token_pos);
#if defined(TARGET_ARCH_DBC)
+ enum CallResult {
+ kHasResult,
+ kNoResult,
+ };
void RecordAfterCallHelper(TokenPosition token_pos,
intptr_t deopt_id,
intptr_t argument_count,
+ CallResult result,
LocationSummary* locs);
- void RecordAfterCall(Instruction* instr);
+ void RecordAfterCall(Instruction* instr, CallResult result);
#endif
private:
diff --git a/runtime/vm/flow_graph_compiler_dbc.cc b/runtime/vm/flow_graph_compiler_dbc.cc
index 745fcf9..eb3660a 100644
--- a/runtime/vm/flow_graph_compiler_dbc.cc
+++ b/runtime/vm/flow_graph_compiler_dbc.cc
@@ -118,6 +118,11 @@
// will be able to find them during materialization.
slot_ix = builder->EmitMaterializationArguments(slot_ix);
+ if (lazy_deopt_with_result_) {
+ ASSERT(reason() == ICData::kDeoptAtCall);
+ builder->AddCopy(NULL, Location::StackSlot(stack_height), slot_ix++);
+ }
+
// For the innermost environment, set outgoing arguments and the locals.
for (intptr_t i = current->Length() - 1;
i >= current->fixed_parameter_count(); i--) {
@@ -179,6 +184,7 @@
void FlowGraphCompiler::RecordAfterCallHelper(TokenPosition token_pos,
intptr_t deopt_id,
intptr_t argument_count,
+ CallResult result,
LocationSummary* locs) {
RecordSafepoint(locs);
// Marks either the continuation point in unoptimized code or the
@@ -190,7 +196,10 @@
// On all other architectures caller drops outgoing arguments itself
// hence the difference.
pending_deoptimization_env_->DropArguments(argument_count);
- AddDeoptIndexAtCall(deopt_id_after);
+ CompilerDeoptInfo* info = AddDeoptIndexAtCall(deopt_id_after);
+ if (result == kHasResult) {
+ info->mark_lazy_deopt_with_result();
+ }
// This descriptor is needed for exception handling in optimized code.
AddCurrentDescriptor(RawPcDescriptors::kOther, deopt_id_after, token_pos);
} else {
@@ -201,9 +210,9 @@
}
-void FlowGraphCompiler::RecordAfterCall(Instruction* instr) {
+void FlowGraphCompiler::RecordAfterCall(Instruction* instr, CallResult result) {
RecordAfterCallHelper(instr->token_pos(), instr->deopt_id(),
- instr->ArgumentCount(), instr->locs());
+ instr->ArgumentCount(), result, instr->locs());
}
@@ -263,7 +272,9 @@
locs->SetStackBit(locs->out(0).reg());
}
AddCurrentDescriptor(RawPcDescriptors::kOther, deopt_id, token_pos);
- RecordAfterCallHelper(token_pos, deopt_id, 0, locs);
+ const intptr_t kArgCount = 0;
+ RecordAfterCallHelper(token_pos, deopt_id, kArgCount,
+ FlowGraphCompiler::kHasResult, locs);
if (is_optimizing()) {
// Assert assignable keeps the instance on the stack as the result,
// all other arguments are popped.
diff --git a/runtime/vm/flow_graph_inliner.cc b/runtime/vm/flow_graph_inliner.cc
index 0621961..6cf0684 100644
--- a/runtime/vm/flow_graph_inliner.cc
+++ b/runtime/vm/flow_graph_inliner.cc
@@ -5,6 +5,7 @@
#include "vm/flow_graph_inliner.h"
#include "vm/aot_optimizer.h"
+#include "vm/precompiler.h"
#include "vm/block_scheduler.h"
#include "vm/branch_optimizer.h"
#include "vm/compiler.h"
@@ -213,8 +214,11 @@
// A collection of call sites to consider for inlining.
class CallSites : public ValueObject {
public:
- explicit CallSites(FlowGraph* flow_graph)
- : static_calls_(), closure_calls_(), instance_calls_() {}
+ explicit CallSites(FlowGraph* flow_graph, intptr_t threshold)
+ : inlining_depth_threshold_(threshold),
+ static_calls_(),
+ closure_calls_(),
+ instance_calls_() {}
struct InstanceCallInfo {
PolymorphicInstanceCallInstr* call;
@@ -357,7 +361,7 @@
intptr_t depth,
GrowableArray<InlinedInfo>* inlined_info) {
ASSERT(graph != NULL);
- if (depth > FLAG_inlining_depth_threshold) {
+ if (depth > inlining_depth_threshold_) {
if (FLAG_print_inlining_tree) {
RecordAllNotInlinedFunction(graph, depth, inlined_info);
}
@@ -367,7 +371,7 @@
// Recognized methods are not treated as normal calls. They don't have
// calls in themselves, so we keep adding those even when at the threshold.
const bool inline_only_recognized_methods =
- (depth == FLAG_inlining_depth_threshold);
+ (depth == inlining_depth_threshold_);
const intptr_t instance_call_start_ix = instance_calls_.length();
const intptr_t static_call_start_ix = static_calls_.length();
@@ -423,6 +427,7 @@
}
private:
+ intptr_t inlining_depth_threshold_;
GrowableArray<StaticCallInfo> static_calls_;
GrowableArray<ClosureCallInfo> closure_calls_;
GrowableArray<InstanceCallInfo> instance_calls_;
@@ -513,7 +518,7 @@
class CallSiteInliner : public ValueObject {
public:
- explicit CallSiteInliner(FlowGraphInliner* inliner)
+ explicit CallSiteInliner(FlowGraphInliner* inliner, intptr_t threshold)
: inliner_(inliner),
caller_graph_(inliner->flow_graph()),
inlined_(false),
@@ -522,6 +527,7 @@
inlined_recursive_call_(false),
inlining_depth_(1),
inlining_recursion_depth_(0),
+ inlining_depth_threshold_(threshold),
collected_call_sites_(NULL),
inlining_call_sites_(NULL),
function_cache_(),
@@ -570,14 +576,14 @@
void InlineCalls() {
// If inlining depth is less then one abort.
- if (FLAG_inlining_depth_threshold < 1) return;
+ if (inlining_depth_threshold_ < 1) return;
if (caller_graph_->function().deoptimization_counter() >=
FLAG_deoptimization_counter_inlining_threshold) {
return;
}
// Create two call site collections to swap between.
- CallSites sites1(caller_graph_);
- CallSites sites2(caller_graph_);
+ CallSites sites1(caller_graph_, inlining_depth_threshold_);
+ CallSites sites2(caller_graph_, inlining_depth_threshold_);
CallSites* call_sites_temp = NULL;
collected_call_sites_ = &sites1;
inlining_call_sites_ = &sites2;
@@ -669,6 +675,15 @@
return false;
}
+ if ((inliner_->precompiler_ != NULL) &&
+ inliner_->precompiler_->HasFeedback() &&
+ (function.usage_counter() <= 0) && !inliner_->AlwaysInline(function)) {
+ TRACE_INLINING(THR_Print(" Bailout: not compiled yet\n"));
+ PRINT_INLINING_TREE("Not compiled", &call_data->caller, &function,
+ call_data->call);
+ return false;
+ }
+
// Type feedback may have been cleared for this function (ClearICDataArray),
// but we need it for inlining.
if (!FLAG_precompiled_mode && (function.ic_data_array() == Array::null())) {
@@ -791,6 +806,16 @@
callee_graph = builder.BuildGraph();
}
}
+#ifdef DART_PRECOMPILER
+ if (FLAG_precompiled_mode) {
+ Precompiler::PopulateWithICData(parsed_function->function(),
+ callee_graph);
+ if (inliner_->precompiler_ != NULL) {
+ inliner_->precompiler_->TryApplyFeedback(
+ parsed_function->function(), callee_graph);
+ }
+ }
+#endif
// The parameter stubs are a copy of the actual arguments providing
// concrete information about the values, for example constant values,
@@ -857,7 +882,6 @@
AotOptimizer optimizer(inliner_->precompiler_, callee_graph,
inliner_->use_speculative_inlining_,
inliner_->inlining_black_list_);
- optimizer.PopulateWithICData();
optimizer.ApplyClassIds();
DEBUG_ASSERT(callee_graph->VerifyUseLists());
@@ -1375,6 +1399,7 @@
bool inlined_recursive_call_;
intptr_t inlining_depth_;
intptr_t inlining_recursion_depth_;
+ intptr_t inlining_depth_threshold_;
CallSites* collected_call_sites_;
CallSites* inlining_call_sites_;
GrowableArray<ParsedFunction*> function_cache_;
@@ -1929,6 +1954,11 @@
return true;
}
+ if (function.is_const()) {
+ // Inlined const fields are smaller than a call.
+ return true;
+ }
+
if (function.IsGetterFunction() || function.IsSetterFunction() ||
IsInlineableOperator(function) ||
(function.kind() == RawFunction::kConstructor)) {
@@ -1962,7 +1992,13 @@
printer.PrintBlocks();
}
- CallSiteInliner inliner(this);
+ intptr_t inlining_depth_threshold = FLAG_inlining_depth_threshold;
+ if ((precompiler_ != NULL) && precompiler_->HasFeedback() &&
+ (top.usage_counter() <= 0)) {
+ inlining_depth_threshold = 1;
+ }
+
+ CallSiteInliner inliner(this, inlining_depth_threshold);
inliner.InlineCalls();
if (FLAG_print_inlining_tree) {
inliner.PrintInlinedInfo(top);
diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc
index 373aa48..78675d9 100644
--- a/runtime/vm/intermediate_language.cc
+++ b/runtime/vm/intermediate_language.cc
@@ -3125,7 +3125,7 @@
}
compiler->AddCurrentDescriptor(RawPcDescriptors::kIcCall, deopt_id(),
token_pos());
- compiler->RecordAfterCall(this);
+ compiler->RecordAfterCall(this, FlowGraphCompiler::kHasResult);
if (compiler->is_optimizing()) {
__ PopLocal(locs()->out(0).reg());
@@ -3273,7 +3273,7 @@
__ StaticCall(ArgumentCount(), argdesc_kidx);
compiler->AddCurrentDescriptor(RawPcDescriptors::kOther, deopt_id(),
token_pos());
- compiler->RecordAfterCall(this);
+ compiler->RecordAfterCall(this, FlowGraphCompiler::kHasResult);
__ PopLocal(locs()->out(0).reg());
} else {
const intptr_t ic_data_kidx = __ AddConstant(*call_ic_data);
@@ -3281,7 +3281,7 @@
__ IndirectStaticCall(ArgumentCount(), argdesc_kidx);
compiler->AddCurrentDescriptor(RawPcDescriptors::kUnoptStaticCall,
deopt_id(), token_pos());
- compiler->RecordAfterCall(this);
+ compiler->RecordAfterCall(this, FlowGraphCompiler::kHasResult);
}
#endif // !defined(TARGET_ARCH_DBC)
}
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
index 0aa3af3..8b843c9 100644
--- a/runtime/vm/intermediate_language.h
+++ b/runtime/vm/intermediate_language.h
@@ -3221,6 +3221,8 @@
const ICData* ic_data() const { return ic_data_; }
bool HasICData() const { return (ic_data() != NULL) && !ic_data()->IsNull(); }
+ void set_ic_data(const ICData* value) { ic_data_ = value; }
+
DECLARE_INSTRUCTION(StaticCall)
virtual CompileType ComputeType() const;
virtual Definition* Canonicalize(FlowGraph* flow_graph);
diff --git a/runtime/vm/intermediate_language_dbc.cc b/runtime/vm/intermediate_language_dbc.cc
index efe48b1..e15e4fa 100644
--- a/runtime/vm/intermediate_language_dbc.cc
+++ b/runtime/vm/intermediate_language_dbc.cc
@@ -204,7 +204,7 @@
__ InstanceOf(negate_result() ? 1 : 0);
compiler->AddCurrentDescriptor(RawPcDescriptors::kOther, deopt_id(),
token_pos());
- compiler->RecordAfterCall(this);
+ compiler->RecordAfterCall(this, FlowGraphCompiler::kHasResult);
if (compiler->is_optimizing()) {
__ PopLocal(locs()->out(0).reg());
}
@@ -227,7 +227,7 @@
__ AssertBoolean(Isolate::Current()->type_checks() ? 1 : 0);
compiler->AddCurrentDescriptor(RawPcDescriptors::kOther, deopt_id(),
token_pos());
- compiler->RecordAfterCall(this);
+ compiler->RecordAfterCall(this, FlowGraphCompiler::kHasResult);
if (compiler->is_optimizing()) {
__ Drop1();
}
@@ -280,7 +280,7 @@
__ StaticCall(instance_call()->ArgumentCount(), argdesc_kidx);
compiler->AddCurrentDescriptor(RawPcDescriptors::kOther, deopt_id(),
instance_call()->token_pos());
- compiler->RecordAfterCall(this);
+ compiler->RecordAfterCall(this, FlowGraphCompiler::kHasResult);
__ PopLocal(locs()->out(0).reg());
}
@@ -301,7 +301,7 @@
}
compiler->AddCurrentDescriptor(RawPcDescriptors::kOther, deopt_id(),
token_pos());
- compiler->RecordAfterCall(this);
+ compiler->RecordAfterCall(this, FlowGraphCompiler::kNoResult);
}
@@ -431,7 +431,7 @@
} else {
__ InitStaticTOS();
}
- compiler->RecordAfterCall(this);
+ compiler->RecordAfterCall(this, FlowGraphCompiler::kNoResult);
}
@@ -449,7 +449,7 @@
const intptr_t argdesc_kidx =
compiler->assembler()->AddConstant(arguments_descriptor);
__ StaticCall(argument_count, argdesc_kidx);
- compiler->RecordAfterCall(this);
+ compiler->RecordAfterCall(this, FlowGraphCompiler::kHasResult);
if (compiler->is_optimizing()) {
__ PopLocal(locs()->out(0).reg());
}
@@ -699,11 +699,11 @@
__ Push(type_arguments);
__ Push(length);
__ CreateArrayTOS();
- compiler->RecordAfterCall(this);
+ compiler->RecordAfterCall(this, FlowGraphCompiler::kHasResult);
__ PopLocal(out);
} else {
__ CreateArrayTOS();
- compiler->RecordAfterCall(this);
+ compiler->RecordAfterCall(this, FlowGraphCompiler::kHasResult);
}
}
@@ -917,7 +917,12 @@
__ PushConstant(CallFunction());
const intptr_t argdesc_kidx = __ AddConstant(arguments_descriptor);
__ StaticCall(kArgumentCount, argdesc_kidx);
- compiler->RecordAfterCall(this);
+ // Note: can't use RecordAfterCall here because
+ // StringInterpolateInstr::ArgumentCount() is 0. However
+ // internally it does a call with 1 argument which needs to
+ // be reflected in the lazy deoptimization environment.
+ compiler->RecordAfterCallHelper(token_pos(), deopt_id(), kArgumentCount,
+ FlowGraphCompiler::kHasResult, locs());
if (compiler->is_optimizing()) {
__ PopLocal(locs()->out(0).reg());
}
@@ -1145,7 +1150,15 @@
compiler->AddExceptionHandler(catch_try_index(), try_index(),
compiler->assembler()->CodeSize(),
catch_handler_types_, needs_stacktrace());
-
+ // On lazy deoptimization we patch the optimized code here to enter the
+ // deoptimization stub.
+ const intptr_t deopt_id = Thread::ToDeoptAfter(GetDeoptId());
+ if (compiler->is_optimizing()) {
+ compiler->AddDeoptIndexAtCall(deopt_id);
+ } else {
+ compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id,
+ TokenPosition::kNoSource);
+ }
if (HasParallelMove()) {
compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
}
@@ -1176,7 +1189,7 @@
__ Throw(0);
compiler->AddCurrentDescriptor(RawPcDescriptors::kOther, deopt_id(),
token_pos());
- compiler->RecordAfterCall(this);
+ compiler->RecordAfterCall(this, FlowGraphCompiler::kNoResult);
__ Trap();
}
@@ -1186,7 +1199,7 @@
__ Throw(1);
compiler->AddCurrentDescriptor(RawPcDescriptors::kOther, deopt_id(),
token_pos());
- compiler->RecordAfterCall(this);
+ compiler->RecordAfterCall(this, FlowGraphCompiler::kNoResult);
__ Trap();
}
diff --git a/runtime/vm/json_parser.h b/runtime/vm/json_parser.h
new file mode 100644
index 0000000..83b9d6b
--- /dev/null
+++ b/runtime/vm/json_parser.h
@@ -0,0 +1,331 @@
+// 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.
+
+#ifndef RUNTIME_VM_JSON_PARSER_H_
+#define RUNTIME_VM_JSON_PARSER_H_
+
+#include "vm/allocation.h"
+#include "vm/zone.h"
+#include "vm/growable_array.h"
+
+namespace dart {
+
+class ParsedJSONArray;
+
+class ParsedJSONValue : public ZoneAllocated {
+ public:
+ virtual ~ParsedJSONValue() {}
+
+ virtual bool IsObject() const { return false; }
+ virtual bool IsArray() const { return false; }
+ virtual bool IsString() const { return false; }
+ virtual bool IsNumber() const { return false; }
+ virtual bool IsBoolean() const { return false; }
+ virtual bool IsError() const { return false; }
+};
+
+class ParsedJSONString : public ParsedJSONValue {
+ public:
+ explicit ParsedJSONString(const char* value) : value_(value) {}
+ bool Equals(const char* other) { return strcmp(value_, other) == 0; }
+ const char* value() { return value_; }
+ virtual bool IsString() const { return true; }
+
+ private:
+ const char* value_;
+};
+
+class ParsedJSONNumber : public ParsedJSONValue {
+ public:
+ explicit ParsedJSONNumber(int64_t value) : value_(value) {}
+
+ int64_t value() { return value_; }
+ virtual bool IsNumber() const { return true; }
+
+ private:
+ int64_t value_;
+};
+
+class ParsedJSONBoolean : public ParsedJSONValue {
+ public:
+ explicit ParsedJSONBoolean(bool value) : value_(value) {}
+
+ bool value() { return value_; }
+ virtual bool IsBoolean() const { return true; }
+
+ private:
+ bool value_;
+};
+
+class ParsedJSONNull : public ParsedJSONValue {
+ public:
+ virtual bool IsNull() const { return true; }
+};
+
+class ParsedJSONObject : public ParsedJSONValue {
+ public:
+ ParsedJSONObject(intptr_t length, ParsedJSONValue** keys_and_values)
+ : length_(length), keys_and_values_(keys_and_values) {}
+
+ ParsedJSONValue* At(const char* key) const {
+ for (intptr_t i = 0; i < length_; i += 2) {
+ ASSERT(keys_and_values_[i]->IsString());
+ ParsedJSONString* jskey =
+ static_cast<ParsedJSONString*>(keys_and_values_[i]);
+ if (jskey->Equals(key)) {
+ return keys_and_values_[i + 1];
+ }
+ }
+ return NULL;
+ }
+
+ virtual bool IsObject() const { return true; }
+
+ ParsedJSONNumber* NumberAt(const char* key) {
+ ParsedJSONValue* member = At(key);
+ if ((member == NULL) || !member->IsNumber()) {
+ return NULL;
+ }
+ return static_cast<ParsedJSONNumber*>(member);
+ }
+
+ ParsedJSONString* StringAt(const char* key) {
+ ParsedJSONValue* member = At(key);
+ if ((member == NULL) || !member->IsString()) {
+ return NULL;
+ }
+ return static_cast<ParsedJSONString*>(member);
+ }
+
+ ParsedJSONBoolean* BooleanAt(const char* key) {
+ ParsedJSONValue* member = At(key);
+ if ((member == NULL) || !member->IsBoolean()) {
+ return NULL;
+ }
+ return static_cast<ParsedJSONBoolean*>(member);
+ }
+
+ inline ParsedJSONArray* ArrayAt(const char* key);
+
+ private:
+ intptr_t length_;
+ ParsedJSONValue** keys_and_values_;
+};
+
+class ParsedJSONArray : public ParsedJSONValue {
+ public:
+ ParsedJSONArray(intptr_t length, ParsedJSONValue** elements)
+ : length_(length), elements_(elements) {}
+
+ ParsedJSONValue* At(intptr_t index) const {
+ ASSERT(index < length_);
+ return elements_[index];
+ }
+
+ intptr_t Length() const { return length_; }
+
+ virtual bool IsArray() const { return true; }
+
+ ParsedJSONObject* ObjectAt(intptr_t index) {
+ ParsedJSONValue* element = At(index);
+ if ((element == NULL) || !element->IsObject()) {
+ return NULL;
+ }
+ return static_cast<ParsedJSONObject*>(element);
+ }
+
+ ParsedJSONNumber* NumberAt(intptr_t index) {
+ ParsedJSONValue* element = At(index);
+ if ((element == NULL) || !element->IsNumber()) {
+ return NULL;
+ }
+ return static_cast<ParsedJSONNumber*>(element);
+ }
+
+ private:
+ intptr_t length_;
+ ParsedJSONValue** elements_;
+};
+
+class ParsedJSONError : public ParsedJSONValue {
+ public:
+ explicit ParsedJSONError(const char* message, intptr_t position)
+ : message_(message), position_(position) {}
+
+ virtual bool IsError() const { return true; }
+
+ const char* message() const { return message_; }
+ intptr_t position() const { return position_; }
+
+ private:
+ const char* message_;
+ intptr_t position_;
+};
+
+class JSONParser {
+ public:
+ JSONParser(const char* buffer, intptr_t length, Zone* zone)
+ : buffer_(buffer), position_(0), length_(length), zone_(zone) {}
+
+ ParsedJSONValue* ParseValue() {
+ ConsumeWhitespace();
+ if (Peek() == '\"') return ParseString();
+ if (IsDigitOrMinus(Peek())) return ParseNumber();
+ if (Peek() == '{') return ParseObject();
+ if (Peek() == '[') return ParseArray();
+ if (PeekAndConsume("true")) return new (zone_) ParsedJSONBoolean(true);
+ if (PeekAndConsume("false")) return new (zone_) ParsedJSONBoolean(false);
+ if (PeekAndConsume("null")) return new (zone_) ParsedJSONNull();
+ return Error("value expected");
+ }
+
+ private:
+ intptr_t Available() const { return length_ - position_; }
+ char Peek() const {
+ if (position_ < length_) return buffer_[position_];
+ return 0;
+ }
+ char Consume() {
+ ASSERT(position_ < length_);
+ return buffer_[position_++];
+ }
+ bool PeekAndConsume(const char* expected) {
+ intptr_t n = strlen(expected);
+ if (Available() < n) return false;
+ if (strncmp(&buffer_[position_], expected, n) != 0) return false;
+ position_ += n;
+ return true;
+ }
+ void ConsumeWhitespace() {
+ while ((Available() > 0) && (buffer_[position_] < ' '))
+ position_++;
+ }
+ bool IsDigit(char c) { return c >= '0' && c <= '9'; }
+ bool IsDigitOrMinus(char c) { return (c == '-') || (c >= '0' && c <= '9'); }
+
+ ParsedJSONValue* ParseString() {
+ ConsumeWhitespace();
+ if (Peek() != '\"') return Error("string expected");
+ Consume();
+ intptr_t start = position_;
+ for (;;) {
+ if (Available() == 0) return Error("unterminated string");
+ if (Consume() == '\"') break;
+ }
+ intptr_t end = position_ - 1;
+
+ char* cstr = zone_->Alloc<char>(end - start + 1);
+ intptr_t dst_pos = 0;
+ for (intptr_t src_pos = start; src_pos < end; src_pos++) {
+ if (buffer_[src_pos] == '\\') {
+ src_pos++;
+ }
+ cstr[dst_pos++] = buffer_[src_pos];
+ }
+ cstr[dst_pos] = '\0';
+
+ return new (zone_) ParsedJSONString(cstr);
+ }
+
+ ParsedJSONValue* ParseNumber() {
+ ConsumeWhitespace();
+ bool negate = false;
+ if (Peek() == '-') {
+ Consume();
+ negate = true;
+ }
+ if (!IsDigit(Peek())) return Error("number expected");
+ int64_t value = 0;
+ for (;;) {
+ if (!IsDigit(Peek())) break;
+ char c = Consume();
+ value *= 10;
+ value += (c - '0');
+ }
+ if (negate) {
+ value = -value;
+ }
+ return new (zone_) ParsedJSONNumber(value);
+ }
+
+ ParsedJSONValue* ParseObject() {
+ ConsumeWhitespace();
+ if (Peek() != '{') return Error("object expected");
+ Consume();
+ ConsumeWhitespace();
+ if (Peek() == '}') return new (zone_) ParsedJSONObject(0, NULL);
+ ZoneGrowableArray<ParsedJSONValue*>* keys_and_values =
+ new (zone_) ZoneGrowableArray<ParsedJSONValue*>(zone_, 6);
+ for (;;) {
+ ParsedJSONValue* key = ParseString();
+ if (key->IsError()) return key;
+ ConsumeWhitespace();
+ if (Consume() != ':') return Error(": expected");
+ ConsumeWhitespace();
+ ParsedJSONValue* value = ParseValue();
+ if (value->IsError()) return value;
+ ConsumeWhitespace();
+
+ keys_and_values->Add(key);
+ keys_and_values->Add(value);
+
+ char c = Consume();
+ if (c == '}') break;
+ if (c != ',') return Error(", expected (object)");
+ ConsumeWhitespace();
+ }
+
+ return new (zone_)
+ ParsedJSONObject(keys_and_values->length(), keys_and_values->data());
+ }
+
+ ParsedJSONValue* ParseArray() {
+ ConsumeWhitespace();
+ if (Peek() != '[') return Error("array expected");
+ Consume();
+ ConsumeWhitespace();
+ if (Peek() == ']') {
+ Consume();
+ return new (zone_) ParsedJSONArray(0, NULL);
+ }
+ ZoneGrowableArray<ParsedJSONValue*>* elements =
+ new (zone_) ZoneGrowableArray<ParsedJSONValue*>(zone_, 6);
+ for (;;) {
+ ParsedJSONValue* element = ParseValue();
+ if (element->IsError()) return element;
+ ConsumeWhitespace();
+
+ elements->Add(element);
+
+ char c = Consume();
+ if (c == ']') break;
+ if (c != ',') return Error(", expected (array)");
+ ConsumeWhitespace();
+ }
+
+ return new (zone_) ParsedJSONArray(elements->length(), elements->data());
+ }
+
+ private:
+ ParsedJSONError* Error(const char* message) {
+ return new (zone_) ParsedJSONError(message, position_);
+ }
+
+ const char* const buffer_;
+ intptr_t position_;
+ intptr_t length_;
+ Zone* zone_;
+};
+
+ParsedJSONArray* ParsedJSONObject::ArrayAt(const char* key) {
+ ParsedJSONValue* member = At(key);
+ if ((member == NULL) || !member->IsArray()) {
+ return NULL;
+ }
+ return static_cast<ParsedJSONArray*>(member);
+}
+
+} // namespace dart
+
+#endif // RUNTIME_VM_JSON_PARSER_H_
diff --git a/runtime/vm/method_recognizer.h b/runtime/vm/method_recognizer.h
index 5ab5eac..043dd70 100644
--- a/runtime/vm/method_recognizer.h
+++ b/runtime/vm/method_recognizer.h
@@ -17,39 +17,39 @@
V(::, identical, ObjectIdentical, Bool, 0x49c6e96a) \
V(ClassID, getID, ClassIDgetID, Smi, 0x528fd455) \
V(Object, Object., ObjectConstructor, Dynamic, 0x681617fe) \
- V(_List, ., ObjectArrayAllocate, Array, 0x63078b15) \
- V(_TypedList, _getInt8, ByteArrayBaseGetInt8, Smi, 0x59e7291d) \
- V(_TypedList, _getUint8, ByteArrayBaseGetUint8, Smi, 0x38d3e5bf) \
- V(_TypedList, _getInt16, ByteArrayBaseGetInt16, Smi, 0x19dde22c) \
- V(_TypedList, _getUint16, ByteArrayBaseGetUint16, Smi, 0x4f3dbe58) \
- V(_TypedList, _getInt32, ByteArrayBaseGetInt32, Dynamic, 0x082db131) \
- V(_TypedList, _getUint32, ByteArrayBaseGetUint32, Dynamic, 0x1dcbfb98) \
- V(_TypedList, _getInt64, ByteArrayBaseGetInt64, Dynamic, 0x61b71474) \
- V(_TypedList, _getFloat32, ByteArrayBaseGetFloat32, Double, 0x63b56e15) \
- V(_TypedList, _getFloat64, ByteArrayBaseGetFloat64, Double, 0x399dacf8) \
+ V(_List, ., ObjectArrayAllocate, Array, 0x375519ad) \
+ V(_TypedList, _getInt8, ByteArrayBaseGetInt8, Smi, 0x7041895a) \
+ V(_TypedList, _getUint8, ByteArrayBaseGetUint8, Smi, 0x336fa3ea) \
+ V(_TypedList, _getInt16, ByteArrayBaseGetInt16, Smi, 0x231bbe2e) \
+ V(_TypedList, _getUint16, ByteArrayBaseGetUint16, Smi, 0x0371785f) \
+ V(_TypedList, _getInt32, ByteArrayBaseGetInt32, Dynamic, 0x65ab3a20) \
+ V(_TypedList, _getUint32, ByteArrayBaseGetUint32, Dynamic, 0x0cb0fcf6) \
+ V(_TypedList, _getInt64, ByteArrayBaseGetInt64, Dynamic, 0x7db75d78) \
+ V(_TypedList, _getFloat32, ByteArrayBaseGetFloat32, Double, 0x6674ea6f) \
+ V(_TypedList, _getFloat64, ByteArrayBaseGetFloat64, Double, 0x236c6e7a) \
V(_TypedList, _getFloat32x4, ByteArrayBaseGetFloat32x4, Float32x4, \
- 0x4761a5be) \
- V(_TypedList, _getInt32x4, ByteArrayBaseGetInt32x4, Int32x4, 0x3053e92c) \
- V(_TypedList, _setInt8, ByteArrayBaseSetInt8, Dynamic, 0x4e82d1e9) \
- V(_TypedList, _setUint8, ByteArrayBaseSetUint8, Dynamic, 0x4f3587fc) \
- V(_TypedList, _setInt16, ByteArrayBaseSetInt16, Dynamic, 0x6cef30ee) \
- V(_TypedList, _setUint16, ByteArrayBaseSetUint16, Dynamic, 0x64f938ac) \
- V(_TypedList, _setInt32, ByteArrayBaseSetInt32, Dynamic, 0x3693c029) \
- V(_TypedList, _setUint32, ByteArrayBaseSetUint32, Dynamic, 0x74bbf260) \
- V(_TypedList, _setInt64, ByteArrayBaseSetInt64, Dynamic, 0x75764edb) \
- V(_TypedList, _setFloat32, ByteArrayBaseSetFloat32, Dynamic, 0x6e72f2a4) \
- V(_TypedList, _setFloat64, ByteArrayBaseSetFloat64, Dynamic, 0x4765edda) \
- V(_TypedList, _setFloat32x4, ByteArrayBaseSetFloat32x4, Dynamic, 0x7cca4533) \
- V(_TypedList, _setInt32x4, ByteArrayBaseSetInt32x4, Dynamic, 0x7631bdbc) \
- V(_StringBase, _interpolate, StringBaseInterpolate, Dynamic, 0x6f98eb49) \
- V(_IntegerImplementation, toDouble, IntegerToDouble, Double, 0x2f409861) \
- V(_Double, _add, DoubleAdd, Double, 0x0021c560) \
- V(_Double, _sub, DoubleSub, Double, 0x419b3c66) \
- V(_Double, _mul, DoubleMul, Double, 0x1a08cbe1) \
- V(_Double, _div, DoubleDiv, Double, 0x38d2770f) \
+ 0x5c367ffb) \
+ V(_TypedList, _getInt32x4, ByteArrayBaseGetInt32x4, Int32x4, 0x772d1c0f) \
+ V(_TypedList, _setInt8, ByteArrayBaseSetInt8, Dynamic, 0x68f17de8) \
+ V(_TypedList, _setUint8, ByteArrayBaseSetUint8, Dynamic, 0x6bb8b747) \
+ V(_TypedList, _setInt16, ByteArrayBaseSetInt16, Dynamic, 0x75b8d278) \
+ V(_TypedList, _setUint16, ByteArrayBaseSetUint16, Dynamic, 0x6e54f794) \
+ V(_TypedList, _setInt32, ByteArrayBaseSetInt32, Dynamic, 0x54123a05) \
+ V(_TypedList, _setUint32, ByteArrayBaseSetUint32, Dynamic, 0x4a3fea0b) \
+ V(_TypedList, _setInt64, ByteArrayBaseSetInt64, Dynamic, 0x1d77d3ec) \
+ V(_TypedList, _setFloat32, ByteArrayBaseSetFloat32, Dynamic, 0x5a11a2f9) \
+ V(_TypedList, _setFloat64, ByteArrayBaseSetFloat64, Dynamic, 0x0edea58b) \
+ V(_TypedList, _setFloat32x4, ByteArrayBaseSetFloat32x4, Dynamic, 0x163bc6cc) \
+ V(_TypedList, _setInt32x4, ByteArrayBaseSetInt32x4, Dynamic, 0x5def39d2) \
+ V(_StringBase, _interpolate, StringBaseInterpolate, Dynamic, 0x084d9f1a) \
+ V(_IntegerImplementation, toDouble, IntegerToDouble, Double, 0x0d8f57ab) \
+ V(_Double, _add, DoubleAdd, Double, 0x2a38277b) \
+ V(_Double, _sub, DoubleSub, Double, 0x4f466391) \
+ V(_Double, _mul, DoubleMul, Double, 0x175e4f66) \
+ V(_Double, _div, DoubleDiv, Double, 0x0854181b) \
V(::, min, MathMin, Dynamic, 0x4276561c) \
V(::, max, MathMax, Dynamic, 0x54121d6a) \
- V(::, _doublePow, MathDoublePow, Double, 0x698eb78d) \
+ V(::, _doublePow, MathDoublePow, Double, 0x01d7b09e) \
V(Float32x4, Float32x4., Float32x4Constructor, Float32x4, 0x05968999) \
V(Float32x4, Float32x4.zero, Float32x4Zero, Float32x4, 0x472a4c46) \
V(Float32x4, Float32x4.splat, Float32x4Splat, Float32x4, 0x00bba1a5) \
@@ -60,22 +60,22 @@
V(Float32x4, shuffle, Float32x4Shuffle, Float32x4, 0x7829101f) \
V(Float32x4, shuffleMix, Float32x4ShuffleMix, Float32x4, 0x4182c06b) \
V(Float32x4, get:signMask, Float32x4GetSignMask, Dynamic, 0x1d07ca93) \
- V(Float32x4, _cmpequal, Float32x4Equal, Int32x4, 0x079804cb) \
- V(Float32x4, _cmpgt, Float32x4GreaterThan, Int32x4, 0x7e441585) \
- V(Float32x4, _cmpgte, Float32x4GreaterThanOrEqual, Int32x4, 0x213f782d) \
- V(Float32x4, _cmplt, Float32x4LessThan, Int32x4, 0x3f481f31) \
- V(Float32x4, _cmplte, Float32x4LessThanOrEqual, Int32x4, 0x061db061) \
- V(Float32x4, _cmpnequal, Float32x4NotEqual, Int32x4, 0x6fada13e) \
- V(Float32x4, _min, Float32x4Min, Float32x4, 0x4505ee78) \
- V(Float32x4, _max, Float32x4Max, Float32x4, 0x071681c6) \
- V(Float32x4, _scale, Float32x4Scale, Float32x4, 0x18c7f49d) \
- V(Float32x4, _sqrt, Float32x4Sqrt, Float32x4, 0x734e6ad0) \
+ V(Float32x4, _cmpequal, Float32x4Equal, Int32x4, 0x16ad0fea) \
+ V(Float32x4, _cmpgt, Float32x4GreaterThan, Int32x4, 0x0641f613) \
+ V(Float32x4, _cmpgte, Float32x4GreaterThanOrEqual, Int32x4, 0x464b8ffc) \
+ V(Float32x4, _cmplt, Float32x4LessThan, Int32x4, 0x3eecd0de) \
+ V(Float32x4, _cmplte, Float32x4LessThanOrEqual, Int32x4, 0x06384754) \
+ V(Float32x4, _cmpnequal, Float32x4NotEqual, Int32x4, 0x2f25ef10) \
+ V(Float32x4, _min, Float32x4Min, Float32x4, 0x1ee6c750) \
+ V(Float32x4, _max, Float32x4Max, Float32x4, 0x4db6bbb4) \
+ V(Float32x4, _scale, Float32x4Scale, Float32x4, 0x52052a66) \
+ V(Float32x4, _sqrt, Float32x4Sqrt, Float32x4, 0x479f6b4a) \
V(Float32x4, _reciprocalSqrt, Float32x4ReciprocalSqrt, Float32x4, \
- 0x5e8a97f6) \
- V(Float32x4, _reciprocal, Float32x4Reciprocal, Float32x4, 0x626f6106) \
- V(Float32x4, _negate, Float32x4Negate, Float32x4, 0x7fb3a154) \
- V(Float32x4, _abs, Float32x4Absolute, Float32x4, 0x1420f447) \
- V(Float32x4, _clamp, Float32x4Clamp, Float32x4, 0x4200222d) \
+ 0x6d35bfcf) \
+ V(Float32x4, _reciprocal, Float32x4Reciprocal, Float32x4, 0x21a56839) \
+ V(Float32x4, _negate, Float32x4Negate, Float32x4, 0x6cfd5db7) \
+ V(Float32x4, _abs, Float32x4Absolute, Float32x4, 0x249b8078) \
+ V(Float32x4, _clamp, Float32x4Clamp, Float32x4, 0x28b06c7a) \
V(Float32x4, withX, Float32x4WithX, Float32x4, 0x4e336aff) \
V(Float32x4, withY, Float32x4WithY, Float32x4, 0x0a72b910) \
V(Float32x4, withZ, Float32x4WithZ, Float32x4, 0x31e93658) \
@@ -87,7 +87,7 @@
0x2f43d3a6) \
V(Float64x2, get:x, Float64x2GetX, Double, 0x58bfb39a) \
V(Float64x2, get:y, Float64x2GetY, Double, 0x3cf4fcfa) \
- V(Float64x2, _negate, Float64x2Negate, Float64x2, 0x64ef7b77) \
+ V(Float64x2, _negate, Float64x2Negate, Float64x2, 0x523937da) \
V(Float64x2, abs, Float64x2Abs, Float64x2, 0x031f9e47) \
V(Float64x2, sqrt, Float64x2Sqrt, Float64x2, 0x77f711dd) \
V(Float64x2, get:signMask, Float64x2GetSignMask, Dynamic, 0x27ddf18d) \
@@ -107,30 +107,30 @@
V(Int32x4, get:signMask, Int32x4GetSignMask, Dynamic, 0x2c1ec9e5) \
V(Int32x4, shuffle, Int32x4Shuffle, Int32x4, 0x20bc0b16) \
V(Int32x4, shuffleMix, Int32x4ShuffleMix, Int32x4, 0x5c7056e1) \
- V(Int32x4, select, Int32x4Select, Float32x4, 0x518ee337) \
+ V(Int32x4, select, Int32x4Select, Float32x4, 0x5c254e86) \
V(Int32x4, withFlagX, Int32x4WithFlagX, Int32x4, 0x0ef58fcf) \
V(Int32x4, withFlagY, Int32x4WithFlagY, Int32x4, 0x6485a9c4) \
V(Int32x4, withFlagZ, Int32x4WithFlagZ, Int32x4, 0x267acdfa) \
V(Int32x4, withFlagW, Int32x4WithFlagW, Int32x4, 0x345ac675) \
- V(Int64List, [], Int64ArrayGetIndexed, Dynamic, 0x0c0c939a) \
- V(Int64List, []=, Int64ArraySetIndexed, Dynamic, 0x3714d004) \
- V(_Bigint, get:_neg, Bigint_getNeg, Bool, 0x7bf17a57) \
- V(_Bigint, get:_used, Bigint_getUsed, Smi, 0x55041013) \
- V(_Bigint, get:_digits, Bigint_getDigits, TypedDataUint32Array, 0x46a6c1b3) \
- V(_HashVMBase, get:_index, LinkedHashMap_getIndex, Dynamic, 0x7d6bb76b) \
- V(_HashVMBase, set:_index, LinkedHashMap_setIndex, Dynamic, 0x4beb13f2) \
- V(_HashVMBase, get:_data, LinkedHashMap_getData, Array, 0x4bf5ccb3) \
- V(_HashVMBase, set:_data, LinkedHashMap_setData, Dynamic, 0x6007556d) \
- V(_HashVMBase, get:_usedData, LinkedHashMap_getUsedData, Smi, 0x15e70845) \
- V(_HashVMBase, set:_usedData, LinkedHashMap_setUsedData, Dynamic, 0x3e8c6edc)\
- V(_HashVMBase, get:_hashMask, LinkedHashMap_getHashMask, Smi, 0x35c5ac00) \
- V(_HashVMBase, set:_hashMask, LinkedHashMap_setHashMask, Dynamic, 0x49adf69e)\
+ V(Int64List, [], Int64ArrayGetIndexed, Dynamic, 0x680ec59b) \
+ V(Int64List, []=, Int64ArraySetIndexed, Dynamic, 0x0872fc15) \
+ V(_Bigint, get:_neg, Bigint_getNeg, Bool, 0x355fa565) \
+ V(_Bigint, get:_used, Bigint_getUsed, Smi, 0x33b9dcd2) \
+ V(_Bigint, get:_digits, Bigint_getDigits, TypedDataUint32Array, 0x68de883a) \
+ V(_HashVMBase, get:_index, LinkedHashMap_getIndex, Dynamic, 0x02468899) \
+ V(_HashVMBase, set:_index, LinkedHashMap_setIndex, Dynamic, 0x577d9e20) \
+ V(_HashVMBase, get:_data, LinkedHashMap_getData, Array, 0x2d7987ee) \
+ V(_HashVMBase, set:_data, LinkedHashMap_setData, Dynamic, 0x1674fb28) \
+ V(_HashVMBase, get:_usedData, LinkedHashMap_getUsedData, Smi, 0x0884b12f) \
+ V(_HashVMBase, set:_usedData, LinkedHashMap_setUsedData, Dynamic, 0x66f792c6)\
+ V(_HashVMBase, get:_hashMask, LinkedHashMap_getHashMask, Smi, 0x32f2c87d) \
+ V(_HashVMBase, set:_hashMask, LinkedHashMap_setHashMask, Dynamic, 0x79ce8c9b)\
V(_HashVMBase, get:_deletedKeys, LinkedHashMap_getDeletedKeys, Smi, \
- 0x306e6a79) \
+ 0x55839904) \
V(_HashVMBase, set:_deletedKeys, LinkedHashMap_setDeletedKeys, Dynamic, \
- 0x3fe95fc2) \
- V(::, _classRangeCheck, ClassRangeCheck, Bool, 0x6279a7b3) \
- V(::, _classRangeCheckNegative, ClassRangeCheckNegated, Bool, 0x4799dac1) \
+ 0x625e50cd) \
+ V(::, _classRangeCheck, ClassRangeCheck, Bool, 0x025e8d82) \
+ V(::, _classRangeCheckNegative, ClassRangeCheckNegated, Bool, 0x32451d73) \
// List of intrinsics:
@@ -138,103 +138,103 @@
#define CORE_LIB_INTRINSIC_LIST(V) \
V(_Smi, ~, Smi_bitNegate, Smi, 0x63bfee11) \
V(_Smi, get:bitLength, Smi_bitLength, Smi, 0x25b2e24c) \
- V(_Smi, _bitAndFromSmi, Smi_bitAndFromSmi, Smi, 0x0df806ed) \
- V(_Bigint, _lsh, Bigint_lsh, Dynamic, 0x5cd95513) \
- V(_Bigint, _rsh, Bigint_rsh, Dynamic, 0x2d68d0e1) \
- V(_Bigint, _absAdd, Bigint_absAdd, Dynamic, 0x492f4865) \
- V(_Bigint, _absSub, Bigint_absSub, Dynamic, 0x174a3a34) \
- V(_Bigint, _mulAdd, Bigint_mulAdd, Dynamic, 0x24ced3ee) \
- V(_Bigint, _sqrAdd, Bigint_sqrAdd, Dynamic, 0x60c6b633) \
- V(_Bigint, _estQuotientDigit, Bigint_estQuotientDigit, Dynamic, 0x2f867482) \
- V(_Montgomery, _mulMod, Montgomery_mulMod, Dynamic, 0x741bed13) \
- V(_Double, >, Double_greaterThan, Bool, 0x569b0a81) \
+ V(_Smi, _bitAndFromSmi, Smi_bitAndFromSmi, Smi, 0x490a4da1) \
+ V(_Bigint, _lsh, Bigint_lsh, Dynamic, 0x0619eb8a) \
+ V(_Bigint, _rsh, Bigint_rsh, Dynamic, 0x0e1b80df) \
+ V(_Bigint, _absAdd, Bigint_absAdd, Dynamic, 0x1a2b6326) \
+ V(_Bigint, _absSub, Bigint_absSub, Dynamic, 0x3bebab4e) \
+ V(_Bigint, _mulAdd, Bigint_mulAdd, Dynamic, 0x7d48a0b3) \
+ V(_Bigint, _sqrAdd, Bigint_sqrAdd, Dynamic, 0x638b5f5d) \
+ V(_Bigint, _estQuotientDigit, Bigint_estQuotientDigit, Dynamic, 0x467dee78) \
+ V(_Montgomery, _mulMod, Montgomery_mulMod, Dynamic, 0x36065c30) \
+ V(_Double, >, Double_greaterThan, Bool, 0x452cd763) \
V(_Double, >=, Double_greaterEqualThan, Bool, 0x6c317340) \
V(_Double, <, Double_lessThan, Bool, 0x26dda4bc) \
V(_Double, <=, Double_lessEqualThan, Bool, 0x1e869d20) \
- V(_Double, ==, Double_equal, Bool, 0x578a1a51) \
- V(_Double, +, Double_add, Double, 0x4bac5dd5) \
- V(_Double, -, Double_sub, Double, 0x62052dbb) \
- V(_Double, *, Double_mul, Double, 0x23d068d8) \
- V(_Double, /, Double_div, Double, 0x48bac1dc) \
+ V(_Double, ==, Double_equal, Bool, 0x5244dca3) \
+ V(_Double, +, Double_add, Double, 0x49b2a530) \
+ V(_Double, -, Double_sub, Double, 0x31833626) \
+ V(_Double, *, Double_mul, Double, 0x21d31f1d) \
+ V(_Double, /, Double_div, Double, 0x3e584fe8) \
V(_Double, get:isNaN, Double_getIsNaN, Bool, 0x0af8ebeb) \
V(_Double, get:isInfinite, Double_getIsInfinite, Bool, 0x0f79e289) \
V(_Double, get:isNegative, Double_getIsNegative, Bool, 0x3a58ff36) \
- V(_Double, _mulFromInteger, Double_mulFromInteger, Double, 0x330e9a36) \
- V(_Double, .fromInteger, DoubleFromInteger, Double, 0x7ef45843) \
+ V(_Double, _mulFromInteger, Double_mulFromInteger, Double, 0x7f565534) \
+ V(_Double, .fromInteger, DoubleFromInteger, Double, 0x04906d0d) \
V(_List, []=, ObjectArraySetIndexed, Dynamic, 0x34d2c72c) \
V(_GrowableList, .withData, GrowableArray_Allocate, GrowableObjectArray, \
- 0x25a786de) \
- V(_GrowableList, add, GrowableArray_add, Dynamic, 0x0d1358ed) \
- V(_RegExp, _ExecuteMatch, RegExp_ExecuteMatch, Dynamic, 0x6036d7fa) \
+ 0x401f3150) \
+ V(_GrowableList, add, GrowableArray_add, Dynamic, 0x71f49ac8) \
+ V(_RegExp, _ExecuteMatch, RegExp_ExecuteMatch, Dynamic, 0x380184b1) \
V(_RegExp, _ExecuteMatchSticky, RegExp_ExecuteMatchSticky, Dynamic, \
- 0x71c67f7d) \
+ 0x79b8f955) \
V(Object, ==, ObjectEquals, Bool, 0x11662ed8) \
V(Object, get:runtimeType, ObjectRuntimeType, Type, 0x00e7c26b) \
- V(Object, _haveSameRuntimeType, ObjectHaveSameRuntimeType, Bool, 0x72aad7e2) \
+ V(Object, _haveSameRuntimeType, ObjectHaveSameRuntimeType, Bool, 0x6532255b) \
V(_StringBase, get:hashCode, String_getHashCode, Smi, 0x78c2eb88) \
V(_StringBase, get:isEmpty, StringBaseIsEmpty, Bool, 0x74c21fca) \
V(_StringBase, _substringMatches, StringBaseSubstringMatches, Bool, \
- 0x2f851deb) \
+ 0x025b2ece) \
V(_StringBase, [], StringBaseCharAt, Dynamic, 0x2cf92c45) \
V(_OneByteString, get:hashCode, OneByteString_getHashCode, Smi, 0x78c2eb88) \
V(_OneByteString, _substringUncheckedNative, \
- OneByteString_substringUnchecked, OneByteString, 0x638c3722) \
- V(_OneByteString, _setAt, OneByteStringSetAt, Dynamic, 0x452533ef) \
+ OneByteString_substringUnchecked, OneByteString, 0x3538ad86) \
+ V(_OneByteString, _setAt, OneByteStringSetAt, Dynamic, 0x6836784f) \
V(_OneByteString, _allocate, OneByteString_allocate, OneByteString, \
- 0x3d4fad8a) \
+ 0x4c0a5574) \
V(_OneByteString, ==, OneByteString_equality, Bool, 0x3f59b700) \
V(_TwoByteString, ==, TwoByteString_equality, Bool, 0x3f59b700) \
#define CORE_INTEGER_LIB_INTRINSIC_LIST(V) \
V(_IntegerImplementation, _addFromInteger, Integer_addFromInteger, \
- Dynamic, 0x79bde54b) \
- V(_IntegerImplementation, +, Integer_add, Dynamic, 0x0e4300c2) \
+ Dynamic, 0x6a10c54a) \
+ V(_IntegerImplementation, +, Integer_add, Dynamic, 0x20192008) \
V(_IntegerImplementation, _subFromInteger, Integer_subFromInteger, Dynamic, \
- 0x3918c1af) \
- V(_IntegerImplementation, -, Integer_sub, Dynamic, 0x0ce294c3) \
+ 0x3fa4b1ed) \
+ V(_IntegerImplementation, -, Integer_sub, Dynamic, 0x5b877969) \
V(_IntegerImplementation, _mulFromInteger, Integer_mulFromInteger, \
- Dynamic, 0x791ecebc) \
- V(_IntegerImplementation, *, Integer_mul, Dynamic, 0x4d8e01a4) \
+ Dynamic, 0x3216e299) \
+ V(_IntegerImplementation, *, Integer_mul, Dynamic, 0x142887aa) \
V(_IntegerImplementation, _moduloFromInteger, Integer_moduloFromInteger, \
- Dynamic, 0x2e72f552) \
- V(_IntegerImplementation, ~/, Integer_truncDivide, Dynamic, 0x3caf6780) \
+ Dynamic, 0x6348b974) \
+ V(_IntegerImplementation, ~/, Integer_truncDivide, Dynamic, 0x5b740346) \
V(_IntegerImplementation, unary-, Integer_negate, Dynamic, 0x59dce57c) \
V(_IntegerImplementation, _bitAndFromInteger, Integer_bitAndFromInteger, \
- Dynamic, 0x1dfbe172) \
- V(_IntegerImplementation, &, Integer_bitAnd, Dynamic, 0x596a453e) \
+ Dynamic, 0x395b1678) \
+ V(_IntegerImplementation, &, Integer_bitAnd, Dynamic, 0x50aab6e4) \
V(_IntegerImplementation, _bitOrFromInteger, Integer_bitOrFromInteger, \
- Dynamic, 0x3d79aa1c) \
- V(_IntegerImplementation, |, Integer_bitOr, Dynamic, 0x071e153c) \
+ Dynamic, 0x6a36b395) \
+ V(_IntegerImplementation, |, Integer_bitOr, Dynamic, 0x40b9d4c2) \
V(_IntegerImplementation, _bitXorFromInteger, Integer_bitXorFromInteger, \
- Dynamic, 0x4fd73f45) \
- V(_IntegerImplementation, ^, Integer_bitXor, Dynamic, 0x0c8aeb3d) \
+ Dynamic, 0x72da93f0) \
+ V(_IntegerImplementation, ^, Integer_bitXor, Dynamic, 0x16edce03) \
V(_IntegerImplementation, _greaterThanFromInteger, \
- Integer_greaterThanFromInt, Bool, 0x2e801bc8) \
- V(_IntegerImplementation, >, Integer_greaterThan, Bool, 0x28287b8f) \
- V(_IntegerImplementation, ==, Integer_equal, Bool, 0x103da147) \
+ Integer_greaterThanFromInt, Bool, 0x4a50ed58) \
+ V(_IntegerImplementation, >, Integer_greaterThan, Bool, 0x6220711f) \
+ V(_IntegerImplementation, ==, Integer_equal, Bool, 0x0d4d7f2c) \
V(_IntegerImplementation, _equalToInteger, Integer_equalToInteger, Bool, \
- 0x7773d51d) \
+ 0x063be842) \
V(_IntegerImplementation, <, Integer_lessThan, Bool, 0x26dda4bc) \
V(_IntegerImplementation, <=, Integer_lessEqualThan, Bool, 0x1e869d20) \
V(_IntegerImplementation, >=, Integer_greaterEqualThan, Bool, 0x6c317340) \
- V(_IntegerImplementation, <<, Integer_shl, Dynamic, 0x4334dfc0) \
- V(_IntegerImplementation, >>, Integer_sar, Dynamic, 0x4a2583a1) \
+ V(_IntegerImplementation, <<, Integer_shl, Dynamic, 0x5f43ef06) \
+ V(_IntegerImplementation, >>, Integer_sar, Dynamic, 0x08a241c7) \
V(_Double, toInt, DoubleToInteger, Dynamic, 0x26ef344b)
#define MATH_LIB_INTRINSIC_LIST(V) \
- V(::, sqrt, MathSqrt, Double, 0x1afb83d4) \
- V(_Random, _nextState, Random_nextState, Dynamic, 0x1e4b0103) \
+ V(::, sqrt, MathSqrt, Double, 0x0a683033) \
+ V(_Random, _nextState, Random_nextState, Dynamic, 0x24d91397) \
#define GRAPH_MATH_LIB_INTRINSIC_LIST(V) \
- V(::, sin, MathSin, Double, 0x0213abe6) \
- V(::, cos, MathCos, Double, 0x79a7611c) \
- V(::, tan, MathTan, Double, 0x4e2e20db) \
- V(::, asin, MathAsin, Double, 0x661ff68b) \
- V(::, acos, MathAcos, Double, 0x44e71d5f) \
- V(::, atan, MathAtan, Double, 0x4436a657) \
- V(::, atan2, MathAtan2, Double, 0x60a40743) \
+ V(::, sin, MathSin, Double, 0x595a044c) \
+ V(::, cos, MathCos, Double, 0x337a20be) \
+ V(::, tan, MathTan, Double, 0x29aba1ea) \
+ V(::, asin, MathAsin, Double, 0x48ec330d) \
+ V(::, acos, MathAcos, Double, 0x22ef2552) \
+ V(::, atan, MathAtan, Double, 0x38473515) \
+ V(::, atan2, MathAtan2, Double, 0x39f1fa41) \
#define TYPED_DATA_LIB_INTRINSIC_LIST(V) \
V(Int8List, ., TypedData_Int8Array_factory, TypedDataInt8Array, 0x2e7749e3) \
@@ -266,45 +266,45 @@
TypedDataFloat64x2Array, 0x18cbf4d9) \
#define GRAPH_TYPED_DATA_INTRINSICS_LIST(V) \
- V(Int8List, [], Int8ArrayGetIndexed, Smi, 0x069af8b3) \
- V(Int8List, []=, Int8ArraySetIndexed, Dynamic, 0x33994cd7) \
- V(Uint8List, [], Uint8ArrayGetIndexed, Smi, 0x027603ed) \
- V(Uint8List, []=, Uint8ArraySetIndexed, Dynamic, 0x060d5256) \
- V(_ExternalUint8Array, [], ExternalUint8ArrayGetIndexed, Smi, 0x027603ed) \
+ V(Int8List, [], Int8ArrayGetIndexed, Smi, 0x5f9a4430) \
+ V(Int8List, []=, Int8ArraySetIndexed, Dynamic, 0x5f880110) \
+ V(Uint8List, [], Uint8ArrayGetIndexed, Smi, 0x1eb150d8) \
+ V(Uint8List, []=, Uint8ArraySetIndexed, Dynamic, 0x4cf76981) \
+ V(_ExternalUint8Array, [], ExternalUint8ArrayGetIndexed, Smi, 0x1eb150d8) \
V(_ExternalUint8Array, []=, ExternalUint8ArraySetIndexed, Dynamic, \
- 0x060d5256) \
- V(Uint8ClampedList, [], Uint8ClampedArrayGetIndexed, Smi, 0x027603ed) \
- V(Uint8ClampedList, []=, Uint8ClampedArraySetIndexed, Dynamic, 0x28f5f058) \
+ 0x4cf76981) \
+ V(Uint8ClampedList, [], Uint8ClampedArrayGetIndexed, Smi, 0x1eb150d8) \
+ V(Uint8ClampedList, []=, Uint8ClampedArraySetIndexed, Dynamic, 0x2224afe1) \
V(_ExternalUint8ClampedArray, [], ExternalUint8ClampedArrayGetIndexed, \
- Smi, 0x027603ed) \
+ Smi, 0x1eb150d8) \
V(_ExternalUint8ClampedArray, []=, ExternalUint8ClampedArraySetIndexed, \
- Dynamic, 0x28f5f058) \
- V(Int16List, [], Int16ArrayGetIndexed, Smi, 0x173cd6a1) \
- V(Int16List, []=, Int16ArraySetIndexed, Dynamic, 0x32f84e3c) \
- V(Uint16List, [], Uint16ArrayGetIndexed, Smi, 0x3ececa2f) \
- V(Uint16List, []=, Uint16ArraySetIndexed, Dynamic, 0x5c3a0bb9) \
- V(Int32List, [], Int32ArrayGetIndexed, Dynamic, 0x262eef09) \
- V(Int32List, []=, Int32ArraySetIndexed, Dynamic, 0x1b05b471) \
- V(Uint32List, [], Uint32ArrayGetIndexed, Dynamic, 0x6040f7fb) \
- V(Uint32List, []=, Uint32ArraySetIndexed, Dynamic, 0x3a4e1119) \
- V(Float64List, [], Float64ArrayGetIndexed, Double, 0x7a27098d) \
- V(Float64List, []=, Float64ArraySetIndexed, Dynamic, 0x139b2465) \
- V(Float32List, [], Float32ArrayGetIndexed, Double, 0x5686528f) \
- V(Float32List, []=, Float32ArraySetIndexed, Dynamic, 0x1b0d90df) \
- V(Float32x4List, [], Float32x4ArrayGetIndexed, Float32x4, 0x01c7017b) \
- V(Float32x4List, []=, Float32x4ArraySetIndexed, Dynamic, 0x56e843aa) \
- V(Int32x4List, [], Int32x4ArrayGetIndexed, Int32x4, 0x08353f8d) \
- V(Int32x4List, []=, Int32x4ArraySetIndexed, Dynamic, 0x1d9a47a5) \
- V(Float64x2List, [], Float64x2ArrayGetIndexed, Float64x2, 0x669b1498) \
- V(Float64x2List, []=, Float64x2ArraySetIndexed, Dynamic, 0x76da6ffe) \
+ Dynamic, 0x2224afe1) \
+ V(Int16List, [], Int16ArrayGetIndexed, Smi, 0x74ea134c) \
+ V(Int16List, []=, Int16ArraySetIndexed, Dynamic, 0x48e25661) \
+ V(Uint16List, [], Uint16ArrayGetIndexed, Smi, 0x756d9a97) \
+ V(Uint16List, []=, Uint16ArraySetIndexed, Dynamic, 0x698f9d4f) \
+ V(Int32List, [], Int32ArrayGetIndexed, Dynamic, 0x61e49de1) \
+ V(Int32List, []=, Int32ArraySetIndexed, Dynamic, 0x55736c63) \
+ V(Uint32List, [], Uint32ArrayGetIndexed, Dynamic, 0x2eaa22d2) \
+ V(Uint32List, []=, Uint32ArraySetIndexed, Dynamic, 0x3c88eeb9) \
+ V(Float64List, [], Float64ArrayGetIndexed, Double, 0x20950e8a) \
+ V(Float64List, []=, Float64ArraySetIndexed, Dynamic, 0x556a0727) \
+ V(Float32List, [], Float32ArrayGetIndexed, Double, 0x7101fa23) \
+ V(Float32List, []=, Float32ArraySetIndexed, Dynamic, 0x5e32c1eb) \
+ V(Float32x4List, [], Float32x4ArrayGetIndexed, Float32x4, 0x28b0a7ef) \
+ V(Float32x4List, []=, Float32x4ArraySetIndexed, Dynamic, 0x4babf032) \
+ V(Int32x4List, [], Int32x4ArrayGetIndexed, Int32x4, 0x619c79a0) \
+ V(Int32x4List, []=, Int32x4ArraySetIndexed, Dynamic, 0x021bd16b) \
+ V(Float64x2List, [], Float64x2ArrayGetIndexed, Float64x2, 0x7a6dd5e5) \
+ V(Float64x2List, []=, Float64x2ArraySetIndexed, Dynamic, 0x3c59fecb) \
V(_TypedList, get:length, TypedDataLength, Smi, 0x2090dc1a) \
V(Float32x4, get:x, Float32x4ShuffleX, Double, 0x63d0c13f) \
V(Float32x4, get:y, Float32x4ShuffleY, Double, 0x20343b1b) \
V(Float32x4, get:z, Float32x4ShuffleZ, Double, 0x13181dba) \
V(Float32x4, get:w, Float32x4ShuffleW, Double, 0x69895020) \
- V(Float32x4, _mul, Float32x4Mul, Float32x4, 0x028d3146) \
- V(Float32x4, _sub, Float32x4Sub, Float32x4, 0x062f78f7) \
- V(Float32x4, _add, Float32x4Add, Float32x4, 0x509f9006) \
+ V(Float32x4, _mul, Float32x4Mul, Float32x4, 0x6183ae12) \
+ V(Float32x4, _sub, Float32x4Sub, Float32x4, 0x22a8d3ea) \
+ V(Float32x4, _add, Float32x4Add, Float32x4, 0x613c30f4) \
#define GRAPH_CORE_INTRINSICS_LIST(V) \
V(_List, get:length, ObjectArrayLength, Smi, 0x25943ad2) \
@@ -312,9 +312,9 @@
V(_ImmutableList, get:length, ImmutableArrayLength, Smi, 0x25943ad2) \
V(_ImmutableList, [], ImmutableArrayGetIndexed, Dynamic, 0x157b4670) \
V(_GrowableList, get:length, GrowableArrayLength, Smi, 0x18dc9df6) \
- V(_GrowableList, get:_capacity, GrowableArrayCapacity, Smi, 0x02734d82) \
- V(_GrowableList, _setData, GrowableArraySetData, Dynamic, 0x0c854013) \
- V(_GrowableList, _setLength, GrowableArraySetLength, Dynamic, 0x1401a7d6) \
+ V(_GrowableList, get:_capacity, GrowableArrayCapacity, Smi, 0x2e03d5a2) \
+ V(_GrowableList, _setData, GrowableArraySetData, Dynamic, 0x6dfc498a) \
+ V(_GrowableList, _setLength, GrowableArraySetLength, Dynamic, 0x257bfc1c) \
V(_GrowableList, [], GrowableArrayGetIndexed, Dynamic, 0x74ad8832) \
V(_GrowableList, []=, GrowableArraySetIndexed, Dynamic, 0x0d6cfe96) \
V(_StringBase, get:length, StringBaseLength, Smi, 0x2a2c1b13) \
@@ -329,7 +329,7 @@
V(_Double, roundToDouble, DoubleRound, Double, 0x2f89c512) \
V(_Double, floorToDouble, DoubleFloor, Double, 0x6aa87a5f) \
V(_Double, ceilToDouble, DoubleCeil, Double, 0x1b045e9e) \
- V(_Double, _modulo, DoubleMod, Double, 0x2e41c4fc)
+ V(_Double, _modulo, DoubleMod, Double, 0x5b8ceed7)
#define GRAPH_INTRINSICS_LIST(V) \
@@ -339,10 +339,10 @@
#define DEVELOPER_LIB_INTRINSIC_LIST(V) \
V(_UserTag, makeCurrent, UserTag_makeCurrent, Dynamic, 0x0b3066fd) \
- V(::, _getDefaultTag, UserTag_defaultTag, Dynamic, 0x14ddc3b7) \
- V(::, _getCurrentTag, Profiler_getCurrentTag, Dynamic, 0x486ee02d) \
+ V(::, _getDefaultTag, UserTag_defaultTag, Dynamic, 0x69f3f1ad) \
+ V(::, _getCurrentTag, Profiler_getCurrentTag, Dynamic, 0x05fa99d2) \
V(::, _isDartStreamEnabled, Timeline_isDartStreamEnabled, Dynamic, \
- 0x1667ce76) \
+ 0x72f13f7a) \
#define ALL_INTRINSICS_NO_INTEGER_LIB_LIST(V) \
CORE_LIB_INTRINSIC_LIST(V) \
@@ -366,133 +366,133 @@
V(_ImmutableList, get:length, ImmutableArrayLength, 0x25943ad2) \
V(_TypedList, get:length, TypedDataLength, 0x2090dc1a) \
V(_GrowableList, get:length, GrowableArrayLength, 0x18dc9df6) \
- V(_GrowableList, get:_capacity, GrowableArrayCapacity, 0x02734d82) \
- V(_GrowableList, add, GrowableListAdd, 0x0d1358ed) \
+ V(_GrowableList, get:_capacity, GrowableArrayCapacity, 0x2e03d5a2) \
+ V(_GrowableList, add, GrowableListAdd, 0x71f49ac8) \
V(_GrowableList, removeLast, GrowableListRemoveLast, 0x7add0363) \
V(_StringBase, get:length, StringBaseLength, 0x2a2c1b13) \
- V(ListIterator, moveNext, ListIteratorMoveNext, 0x3f892e71) \
- V(_FixedSizeArrayIterator, moveNext, FixedListIteratorMoveNext, 0x5681c902) \
+ V(ListIterator, moveNext, ListIteratorMoveNext, 0x4f8ff9cc) \
+ V(_FixedSizeArrayIterator, moveNext, FixedListIteratorMoveNext, 0x50e0604b) \
V(_GrowableList, get:iterator, GrowableArrayIterator, 0x6db11a73) \
V(_GrowableList, forEach, GrowableArrayForEach, 0x250036fe) \
- V(_List, ., ObjectArrayAllocate, 0x63078b15) \
+ V(_List, ., ObjectArrayAllocate, 0x375519ad) \
V(ListMixin, get:isEmpty, ListMixinIsEmpty, 0x787d9bc6) \
- V(_List, get:iterator, ObjectArrayIterator, 0x119cf41a) \
+ V(_List, get:iterator, ObjectArrayIterator, 0x7e634791) \
V(_List, forEach, ObjectArrayForEach, 0x0abce191) \
- V(_List, _slice, ObjectArraySlice, 0x3219e715) \
- V(_ImmutableList, get:iterator, ImmutableArrayIterator, 0x119cf41a) \
+ V(_List, _slice, ObjectArraySlice, 0x01b71c13) \
+ V(_ImmutableList, get:iterator, ImmutableArrayIterator, 0x7e634791) \
V(_ImmutableList, forEach, ImmutableArrayForEach, 0x0abce191) \
- V(_Uint8ArrayView, [], Uint8ArrayViewGetIndexed, 0x4fc6b3d3) \
- V(_Uint8ArrayView, []=, Uint8ArrayViewSetIndexed, 0x2032fdf0) \
- V(_Int8ArrayView, [], Int8ArrayViewGetIndexed, 0x12036952) \
- V(_Int8ArrayView, []=, Int8ArrayViewSetIndexed, 0x6d881658) \
- V(_ByteDataView, setInt8, ByteDataViewSetInt8, 0x275cbdca) \
- V(_ByteDataView, setUint8, ByteDataViewSetUint8, 0x62774e77) \
- V(_ByteDataView, setInt16, ByteDataViewSetInt16, 0x7a43c6c2) \
- V(_ByteDataView, setUint16, ByteDataViewSetUint16, 0x64dd988f) \
- V(_ByteDataView, setInt32, ByteDataViewSetInt32, 0x3363264a) \
- V(_ByteDataView, setUint32, ByteDataViewSetUint32, 0x158f9899) \
- V(_ByteDataView, setInt64, ByteDataViewSetInt64, 0x480f73a5) \
- V(_ByteDataView, setUint64, ByteDataViewSetUint64, 0x5c23db8c) \
- V(_ByteDataView, setFloat32, ByteDataViewSetFloat32, 0x4f76c49a) \
- V(_ByteDataView, setFloat64, ByteDataViewSetFloat64, 0x5e1ddd4f) \
- V(_ByteDataView, getInt8, ByteDataViewGetInt8, 0x01bac87d) \
- V(_ByteDataView, getUint8, ByteDataViewGetUint8, 0x129dab34) \
- V(_ByteDataView, getInt16, ByteDataViewGetInt16, 0x60282377) \
- V(_ByteDataView, getUint16, ByteDataViewGetUint16, 0x10edcd89) \
- V(_ByteDataView, getInt32, ByteDataViewGetInt32, 0x79630f81) \
- V(_ByteDataView, getUint32, ByteDataViewGetUint32, 0x220d3da8) \
- V(_ByteDataView, getInt64, ByteDataViewGetInt64, 0x757dd5c8) \
- V(_ByteDataView, getUint64, ByteDataViewGetUint64, 0x2fab992e) \
- V(_ByteDataView, getFloat32, ByteDataViewGetFloat32, 0x387e9fc6) \
- V(_ByteDataView, getFloat64, ByteDataViewGetFloat64, 0x5396432d) \
- V(::, exp, MathExp, 0x5b894d7b) \
- V(::, log, MathLog, 0x2e25132c) \
+ V(_Uint8ArrayView, [], Uint8ArrayViewGetIndexed, 0x760ba8c2) \
+ V(_Uint8ArrayView, []=, Uint8ArrayViewSetIndexed, 0x44fc1997) \
+ V(_Int8ArrayView, [], Int8ArrayViewGetIndexed, 0x7735aad3) \
+ V(_Int8ArrayView, []=, Int8ArrayViewSetIndexed, 0x4237db0d) \
+ V(_ByteDataView, setInt8, ByteDataViewSetInt8, 0x66702980) \
+ V(_ByteDataView, setUint8, ByteDataViewSetUint8, 0x7c729d61) \
+ V(_ByteDataView, setInt16, ByteDataViewSetInt16, 0x203478e8) \
+ V(_ByteDataView, setUint16, ByteDataViewSetUint16, 0x16c35617) \
+ V(_ByteDataView, setInt32, ByteDataViewSetInt32, 0x200c1aae) \
+ V(_ByteDataView, setUint32, ByteDataViewSetUint32, 0x281c378e) \
+ V(_ByteDataView, setInt64, ByteDataViewSetInt64, 0x10595a04) \
+ V(_ByteDataView, setUint64, ByteDataViewSetUint64, 0x364fcc46) \
+ V(_ByteDataView, setFloat32, ByteDataViewSetFloat32, 0x30628609) \
+ V(_ByteDataView, setFloat64, ByteDataViewSetFloat64, 0x331b1f4b) \
+ V(_ByteDataView, getInt8, ByteDataViewGetInt8, 0x62761d8f) \
+ V(_ByteDataView, getUint8, ByteDataViewGetUint8, 0x579a5e34) \
+ V(_ByteDataView, getInt16, ByteDataViewGetInt16, 0x73e0175b) \
+ V(_ByteDataView, getUint16, ByteDataViewGetUint16, 0x3691576a) \
+ V(_ByteDataView, getInt32, ByteDataViewGetInt32, 0x44d407a8) \
+ V(_ByteDataView, getUint32, ByteDataViewGetUint32, 0x160c7450) \
+ V(_ByteDataView, getInt64, ByteDataViewGetInt64, 0x02a2ffca) \
+ V(_ByteDataView, getUint64, ByteDataViewGetUint64, 0x4dd4eedd) \
+ V(_ByteDataView, getFloat32, ByteDataViewGetFloat32, 0x474b4719) \
+ V(_ByteDataView, getFloat64, ByteDataViewGetFloat64, 0x47207cf7) \
+ V(::, exp, MathExp, 0x4ccba23a) \
+ V(::, log, MathLog, 0x3908fd3c) \
V(::, max, MathMax, 0x54121d6a) \
V(::, min, MathMin, 0x4276561c) \
- V(::, pow, MathPow, 0x438e3089) \
- V(::, _classRangeCheck, ClassRangeCheck, 0x6279a7b3) \
- V(::, _classRangeCheckNegative, ClassRangeCheckNegated, 0x4799dac1) \
+ V(::, pow, MathPow, 0x443379a8) \
+ V(::, _classRangeCheck, ClassRangeCheck, 0x025e8d82) \
+ V(::, _classRangeCheckNegative, ClassRangeCheckNegated, 0x32451d73) \
V(Lists, copy, ListsCopy, 0x21a194fa) \
- V(_Bigint, get:_neg, Bigint_getNeg, 0x7bf17a57) \
- V(_Bigint, get:_used, Bigint_getUsed, 0x55041013) \
- V(_Bigint, get:_digits, Bigint_getDigits, 0x46a6c1b3) \
- V(_HashVMBase, get:_index, LinkedHashMap_getIndex, 0x7d6bb76b) \
- V(_HashVMBase, set:_index, LinkedHashMap_setIndex, 0x4beb13f2) \
- V(_HashVMBase, get:_data, LinkedHashMap_getData, 0x4bf5ccb3) \
- V(_HashVMBase, set:_data, LinkedHashMap_setData, 0x6007556d) \
- V(_HashVMBase, get:_usedData, LinkedHashMap_getUsedData, 0x15e70845) \
- V(_HashVMBase, set:_usedData, LinkedHashMap_setUsedData, 0x3e8c6edc) \
- V(_HashVMBase, get:_hashMask, LinkedHashMap_getHashMask, 0x35c5ac00) \
- V(_HashVMBase, set:_hashMask, LinkedHashMap_setHashMask, 0x49adf69e) \
- V(_HashVMBase, get:_deletedKeys, LinkedHashMap_getDeletedKeys, 0x306e6a79) \
- V(_HashVMBase, set:_deletedKeys, LinkedHashMap_setDeletedKeys, 0x3fe95fc2) \
+ V(_Bigint, get:_neg, Bigint_getNeg, 0x355fa565) \
+ V(_Bigint, get:_used, Bigint_getUsed, 0x33b9dcd2) \
+ V(_Bigint, get:_digits, Bigint_getDigits, 0x68de883a) \
+ V(_HashVMBase, get:_index, LinkedHashMap_getIndex, 0x02468899) \
+ V(_HashVMBase, set:_index, LinkedHashMap_setIndex, 0x577d9e20) \
+ V(_HashVMBase, get:_data, LinkedHashMap_getData, 0x2d7987ee) \
+ V(_HashVMBase, set:_data, LinkedHashMap_setData, 0x1674fb28) \
+ V(_HashVMBase, get:_usedData, LinkedHashMap_getUsedData, 0x0884b12f) \
+ V(_HashVMBase, set:_usedData, LinkedHashMap_setUsedData, 0x66f792c6) \
+ V(_HashVMBase, get:_hashMask, LinkedHashMap_getHashMask, 0x32f2c87d) \
+ V(_HashVMBase, set:_hashMask, LinkedHashMap_setHashMask, 0x79ce8c9b) \
+ V(_HashVMBase, get:_deletedKeys, LinkedHashMap_getDeletedKeys, 0x55839904) \
+ V(_HashVMBase, set:_deletedKeys, LinkedHashMap_setDeletedKeys, 0x625e50cd) \
// A list of core function that should never be inlined.
#define INLINE_BLACK_LIST(V) \
- V(::, asin, MathAsin, 0x661ff68b) \
- V(::, acos, MathAcos, 0x44e71d5f) \
- V(::, atan, MathAtan, 0x4436a657) \
- V(::, atan2, MathAtan2, 0x60a40743) \
- V(::, cos, MathCos, 0x79a7611c) \
- V(::, sin, MathSin, 0x0213abe6) \
- V(::, sqrt, MathSqrt, 0x1afb83d4) \
- V(::, tan, MathTan, 0x4e2e20db) \
- V(_Bigint, _lsh, Bigint_lsh, 0x5cd95513) \
- V(_Bigint, _rsh, Bigint_rsh, 0x2d68d0e1) \
- V(_Bigint, _absAdd, Bigint_absAdd, 0x492f4865) \
- V(_Bigint, _absSub, Bigint_absSub, 0x174a3a34) \
- V(_Bigint, _mulAdd, Bigint_mulAdd, 0x24ced3ee) \
- V(_Bigint, _sqrAdd, Bigint_sqrAdd, 0x60c6b633) \
- V(_Bigint, _estQuotientDigit, Bigint_estQuotientDigit, 0x2f867482) \
- V(_Montgomery, _mulMod, Montgomery_mulMod, 0x741bed13) \
- V(_Double, >, Double_greaterThan, 0x569b0a81) \
+ V(::, asin, MathAsin, 0x48ec330d) \
+ V(::, acos, MathAcos, 0x22ef2552) \
+ V(::, atan, MathAtan, 0x38473515) \
+ V(::, atan2, MathAtan2, 0x39f1fa41) \
+ V(::, cos, MathCos, 0x337a20be) \
+ V(::, sin, MathSin, 0x595a044c) \
+ V(::, sqrt, MathSqrt, 0x0a683033) \
+ V(::, tan, MathTan, 0x29aba1ea) \
+ V(_Bigint, _lsh, Bigint_lsh, 0x0619eb8a) \
+ V(_Bigint, _rsh, Bigint_rsh, 0x0e1b80df) \
+ V(_Bigint, _absAdd, Bigint_absAdd, 0x1a2b6326) \
+ V(_Bigint, _absSub, Bigint_absSub, 0x3bebab4e) \
+ V(_Bigint, _mulAdd, Bigint_mulAdd, 0x7d48a0b3) \
+ V(_Bigint, _sqrAdd, Bigint_sqrAdd, 0x638b5f5d) \
+ V(_Bigint, _estQuotientDigit, Bigint_estQuotientDigit, 0x467dee78) \
+ V(_Montgomery, _mulMod, Montgomery_mulMod, 0x36065c30) \
+ V(_Double, >, Double_greaterThan, 0x452cd763) \
V(_Double, >=, Double_greaterEqualThan, 0x6c317340) \
V(_Double, <, Double_lessThan, 0x26dda4bc) \
V(_Double, <=, Double_lessEqualThan, 0x1e869d20) \
- V(_Double, ==, Double_equal, 0x578a1a51) \
- V(_Double, +, Double_add, 0x4bac5dd5) \
- V(_Double, -, Double_sub, 0x62052dbb) \
- V(_Double, *, Double_mul, 0x23d068d8) \
- V(_Double, /, Double_div, 0x48bac1dc) \
- V(_IntegerImplementation, +, Integer_add, 0x0e4300c2) \
- V(_IntegerImplementation, -, Integer_sub, 0x0ce294c3) \
- V(_IntegerImplementation, *, Integer_mul, 0x4d8e01a4) \
- V(_IntegerImplementation, ~/, Integer_truncDivide, 0x3caf6780) \
+ V(_Double, ==, Double_equal, 0x5244dca3) \
+ V(_Double, +, Double_add, 0x49b2a530) \
+ V(_Double, -, Double_sub, 0x31833626) \
+ V(_Double, *, Double_mul, 0x21d31f1d) \
+ V(_Double, /, Double_div, 0x3e584fe8) \
+ V(_IntegerImplementation, +, Integer_add, 0x20192008) \
+ V(_IntegerImplementation, -, Integer_sub, 0x5b877969) \
+ V(_IntegerImplementation, *, Integer_mul, 0x142887aa) \
+ V(_IntegerImplementation, ~/, Integer_truncDivide, 0x5b740346) \
V(_IntegerImplementation, unary-, Integer_negate, 0x59dce57c) \
- V(_IntegerImplementation, &, Integer_bitAnd, 0x596a453e) \
- V(_IntegerImplementation, |, Integer_bitOr, 0x071e153c) \
- V(_IntegerImplementation, ^, Integer_bitXor, 0x0c8aeb3d) \
- V(_IntegerImplementation, >, Integer_greaterThan, 0x28287b8f) \
- V(_IntegerImplementation, ==, Integer_equal, 0x103da147) \
+ V(_IntegerImplementation, &, Integer_bitAnd, 0x50aab6e4) \
+ V(_IntegerImplementation, |, Integer_bitOr, 0x40b9d4c2) \
+ V(_IntegerImplementation, ^, Integer_bitXor, 0x16edce03) \
+ V(_IntegerImplementation, >, Integer_greaterThan, 0x6220711f) \
+ V(_IntegerImplementation, ==, Integer_equal, 0x0d4d7f2c) \
V(_IntegerImplementation, <, Integer_lessThan, 0x26dda4bc) \
V(_IntegerImplementation, <=, Integer_lessEqualThan, 0x1e869d20) \
V(_IntegerImplementation, >=, Integer_greaterEqualThan, 0x6c317340) \
- V(_IntegerImplementation, <<, Integer_shl, 0x4334dfc0) \
- V(_IntegerImplementation, >>, Integer_sar, 0x4a2583a1) \
+ V(_IntegerImplementation, <<, Integer_shl, 0x5f43ef06) \
+ V(_IntegerImplementation, >>, Integer_sar, 0x08a241c7) \
// A list of core functions that internally dispatch based on received id.
#define POLYMORPHIC_TARGET_LIST(V) \
V(_StringBase, [], StringBaseCharAt, 0x2cf92c45) \
- V(_TypedList, _getInt8, ByteArrayBaseGetInt8, 0x59e7291d) \
- V(_TypedList, _getUint8, ByteArrayBaseGetUint8, 0x38d3e5bf) \
- V(_TypedList, _getInt16, ByteArrayBaseGetInt16, 0x19dde22c) \
- V(_TypedList, _getUint16, ByteArrayBaseGetUint16, 0x4f3dbe58) \
- V(_TypedList, _getInt32, ByteArrayBaseGetInt32, 0x082db131) \
- V(_TypedList, _getUint32, ByteArrayBaseGetUint32, 0x1dcbfb98) \
- V(_TypedList, _getFloat32, ByteArrayBaseGetFloat32, 0x63b56e15) \
- V(_TypedList, _getFloat64, ByteArrayBaseGetFloat64, 0x399dacf8) \
- V(_TypedList, _getFloat32x4, ByteArrayBaseGetFloat32x4, 0x4761a5be) \
- V(_TypedList, _getInt32x4, ByteArrayBaseGetInt32x4, 0x3053e92c) \
- V(_TypedList, _setInt8, ByteArrayBaseSetInt8, 0x4e82d1e9) \
- V(_TypedList, _setUint8, ByteArrayBaseSetInt8, 0x4f3587fc) \
- V(_TypedList, _setInt16, ByteArrayBaseSetInt16, 0x6cef30ee) \
- V(_TypedList, _setUint16, ByteArrayBaseSetInt16, 0x64f938ac) \
- V(_TypedList, _setInt32, ByteArrayBaseSetInt32, 0x3693c029) \
- V(_TypedList, _setUint32, ByteArrayBaseSetUint32, 0x74bbf260) \
- V(_TypedList, _setFloat32, ByteArrayBaseSetFloat32, 0x6e72f2a4) \
- V(_TypedList, _setFloat64, ByteArrayBaseSetFloat64, 0x4765edda) \
- V(_TypedList, _setFloat32x4, ByteArrayBaseSetFloat32x4, 0x7cca4533) \
- V(_TypedList, _setInt32x4, ByteArrayBaseSetInt32x4, 0x7631bdbc) \
+ V(_TypedList, _getInt8, ByteArrayBaseGetInt8, 0x7041895a) \
+ V(_TypedList, _getUint8, ByteArrayBaseGetUint8, 0x336fa3ea) \
+ V(_TypedList, _getInt16, ByteArrayBaseGetInt16, 0x231bbe2e) \
+ V(_TypedList, _getUint16, ByteArrayBaseGetUint16, 0x0371785f) \
+ V(_TypedList, _getInt32, ByteArrayBaseGetInt32, 0x65ab3a20) \
+ V(_TypedList, _getUint32, ByteArrayBaseGetUint32, 0x0cb0fcf6) \
+ V(_TypedList, _getFloat32, ByteArrayBaseGetFloat32, 0x6674ea6f) \
+ V(_TypedList, _getFloat64, ByteArrayBaseGetFloat64, 0x236c6e7a) \
+ V(_TypedList, _getFloat32x4, ByteArrayBaseGetFloat32x4, 0x5c367ffb) \
+ V(_TypedList, _getInt32x4, ByteArrayBaseGetInt32x4, 0x772d1c0f) \
+ V(_TypedList, _setInt8, ByteArrayBaseSetInt8, 0x68f17de8) \
+ V(_TypedList, _setUint8, ByteArrayBaseSetInt8, 0x6bb8b747) \
+ V(_TypedList, _setInt16, ByteArrayBaseSetInt16, 0x75b8d278) \
+ V(_TypedList, _setUint16, ByteArrayBaseSetInt16, 0x6e54f794) \
+ V(_TypedList, _setInt32, ByteArrayBaseSetInt32, 0x54123a05) \
+ V(_TypedList, _setUint32, ByteArrayBaseSetUint32, 0x4a3fea0b) \
+ V(_TypedList, _setFloat32, ByteArrayBaseSetFloat32, 0x5a11a2f9) \
+ V(_TypedList, _setFloat64, ByteArrayBaseSetFloat64, 0x0edea58b) \
+ V(_TypedList, _setFloat32x4, ByteArrayBaseSetFloat32x4, 0x163bc6cc) \
+ V(_TypedList, _setInt32x4, ByteArrayBaseSetInt32x4, 0x5def39d2) \
V(Object, get:runtimeType, ObjectRuntimeType, 0x00e7c26b)
// clang-format on
@@ -540,9 +540,9 @@
// List of recognized list factories:
// (factory-name-symbol, result-cid, fingerprint).
#define RECOGNIZED_LIST_FACTORY_LIST(V) \
- V(_ListFactory, kArrayCid, 0x63078b15) \
- V(_GrowableListWithData, kGrowableObjectArrayCid, 0x25a786de) \
- V(_GrowableListFactory, kGrowableObjectArrayCid, 0x4f4d4790) \
+ V(_ListFactory, kArrayCid, 0x375519ad) \
+ V(_GrowableListWithData, kGrowableObjectArrayCid, 0x401f3150) \
+ V(_GrowableListFactory, kGrowableObjectArrayCid, 0x0b8d9feb) \
V(_Int8ArrayFactory, kTypedDataInt8ArrayCid, 0x2e7749e3) \
V(_Uint8ArrayFactory, kTypedDataUint8ArrayCid, 0x6ab75439) \
V(_Uint8ClampedArrayFactory, kTypedDataUint8ClampedArrayCid, 0x183129d7) \
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index b3ae566..14a9b63 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -210,6 +210,28 @@
}
+// Remove private keys, but retain getter/setter/constructor/mixin manglings.
+RawString* String::RemovePrivateKey(const String& name) {
+ ASSERT(name.IsOneByteString());
+ GrowableArray<uint8_t> without_key(name.Length());
+ intptr_t i = 0;
+ while (i < name.Length()) {
+ while (i < name.Length()) {
+ uint8_t c = name.CharAt(i++);
+ if (c == '@') break;
+ without_key.Add(c);
+ }
+ while (i < name.Length()) {
+ uint8_t c = name.CharAt(i);
+ if ((c < '0') || (c > '9')) break;
+ i++;
+ }
+ }
+
+ return String::FromLatin1(without_key.data(), without_key.length());
+}
+
+
// Takes a vm internal name and makes it suitable for external user.
//
// Examples:
@@ -7018,28 +7040,8 @@
// Construct fingerprint from token stream. The token stream contains also
// arguments.
int32_t Function::SourceFingerprint() const {
- uint32_t result = 0;
- 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();
- if (obj.IsSmi()) {
- val = Smi::Cast(obj).Value();
- } else {
- literal = tokens_iterator.MakeLiteralToken(obj);
- val = literal.Hash();
- }
- result = 31 * result + val;
- tokens_iterator.Advance();
- }
- result = result & ((static_cast<uint32_t>(1) << 31) - 1);
- ASSERT(result <= static_cast<uint32_t>(kMaxInt32));
- return result;
+ return Script::Handle(script()).SourceFingerprint(token_pos(),
+ end_token_pos());
}
@@ -7139,7 +7141,7 @@
if (recalculatingFingerprints) {
// This output can be copied into a file, then used with sed
// to replace the old values.
- // sed -i .bak -f /tmp/newkeys runtime/vm/method_recognizer.h
+ // sed -i.bak -f /tmp/newkeys runtime/vm/method_recognizer.h
THR_Print("s/0x%08x/0x%08x/\n", fp, SourceFingerprint());
} else {
THR_Print(
@@ -9002,6 +9004,43 @@
}
+int32_t Script::SourceFingerprint() const {
+ return SourceFingerprint(TokenPosition(TokenPosition::kMinSourcePos),
+ TokenPosition(TokenPosition::kMaxSourcePos));
+}
+
+
+int32_t Script::SourceFingerprint(TokenPosition start,
+ TokenPosition end) const {
+ uint32_t result = 0;
+ Zone* zone = Thread::Current()->zone();
+ TokenStream::Iterator tokens_iterator(
+ zone, TokenStream::Handle(zone, tokens()), start);
+ Object& obj = Object::Handle(zone);
+ String& literal = String::Handle(zone);
+ while ((tokens_iterator.CurrentTokenKind() != Token::kEOS) &&
+ (tokens_iterator.CurrentPosition() < end)) {
+ uint32_t val = 0;
+ obj = tokens_iterator.CurrentToken();
+ if (obj.IsSmi()) {
+ val = Smi::Cast(obj).Value();
+ } else {
+ literal = tokens_iterator.MakeLiteralToken(obj);
+ if (tokens_iterator.CurrentTokenKind() == Token::kIDENT ||
+ tokens_iterator.CurrentTokenKind() == Token::kINTERPOL_VAR) {
+ literal = String::RemovePrivateKey(literal);
+ }
+ val = literal.Hash();
+ }
+ result = 31 * result + val;
+ tokens_iterator.Advance();
+ }
+ result = result & ((static_cast<uint32_t>(1) << 31) - 1);
+ ASSERT(result <= static_cast<uint32_t>(kMaxInt32));
+ return result;
+}
+
+
RawString* Script::GetLine(intptr_t line_number, Heap::Space space) const {
const String& src = String::Handle(Source());
if (src.IsNull()) {
@@ -12957,7 +12996,8 @@
}
void ICData::AddCheck(const GrowableArray<intptr_t>& class_ids,
- const Function& target) const {
+ const Function& target,
+ intptr_t count) const {
ASSERT(!target.IsNull());
ASSERT((target.name() == target_name()) || ValidateInterceptor(target));
DEBUG_ASSERT(!HasCheck(class_ids));
@@ -13001,7 +13041,7 @@
}
ASSERT(!target.IsNull());
data.SetAt(data_pos++, target);
- value = Smi::New(1);
+ value = Smi::New(count);
data.SetAt(data_pos, value);
// Multithreaded access to ICData requires setting of array to be the last
// operation.
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 7b73349..f3a4d29 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -1506,7 +1506,7 @@
friend class Object;
friend class Type;
friend class Intrinsifier;
- friend class Precompiler;
+ friend class ProgramVisitor;
};
@@ -1974,7 +1974,8 @@
// Adds one more class test to ICData. Length of 'classes' must be equal to
// the number of arguments tested. Use only for num_args_tested > 1.
void AddCheck(const GrowableArray<intptr_t>& class_ids,
- const Function& target) const;
+ const Function& target,
+ intptr_t count = 1) const;
// Adds sorted so that Smi is the first class-id. Use only for
// num_args_tested == 1.
void AddReceiverCheck(intptr_t receiver_class_id,
@@ -3547,6 +3548,9 @@
TokenPosition* first_token_index,
TokenPosition* last_token_index) const;
+ int32_t SourceFingerprint() const;
+ int32_t SourceFingerprint(TokenPosition start, TokenPosition end) const;
+
static intptr_t InstanceSize() {
return RoundedAllocationSize(sizeof(RawScript));
}
@@ -6902,6 +6906,8 @@
static RawString* ToLowerCase(const String& str,
Heap::Space space = Heap::kNew);
+ static RawString* RemovePrivateKey(const String& name);
+
static RawString* ScrubName(const String& name);
static RawString* ScrubNameRetainPrivate(const String& name);
diff --git a/runtime/vm/pages.cc b/runtime/vm/pages.cc
index 268bebf..4c7d49d 100644
--- a/runtime/vm/pages.cc
+++ b/runtime/vm/pages.cc
@@ -139,6 +139,8 @@
void HeapPage::WriteProtect(bool read_only) {
+ ASSERT(!embedder_allocated());
+
VirtualMemory::Protection prot;
if (read_only) {
if (type_ == kExecutable) {
@@ -1100,7 +1102,13 @@
if (*first == NULL) {
*first = page;
} else {
+ if (is_executable && FLAG_write_protect_code) {
+ (*tail)->WriteProtect(false);
+ }
(*tail)->set_next(page);
+ if (is_executable && FLAG_write_protect_code) {
+ (*tail)->WriteProtect(true);
+ }
}
(*tail) = page;
}
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index 1286d7c..9b87e85 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -70,7 +70,6 @@
assert_initializer,
false,
"Allow asserts in initializer lists.");
-DEFINE_FLAG(bool, assert_message, false, "Allow message in assert statements");
DECLARE_FLAG(bool, profile_vm);
DECLARE_FLAG(bool, trace_service);
@@ -9165,7 +9164,7 @@
const TokenPosition condition_pos = TokenPos();
if (!I->asserts()) {
SkipExpr();
- if (FLAG_assert_message && (CurrentToken() == Token::kCOMMA)) {
+ if (CurrentToken() == Token::kCOMMA) {
ConsumeToken();
SkipExpr();
}
@@ -9182,7 +9181,7 @@
const TokenPosition condition_end = TokenPos();
AstNode* message = NULL;
TokenPosition message_pos = TokenPosition::kNoSource;
- if (FLAG_assert_message && CurrentToken() == Token::kCOMMA) {
+ if (CurrentToken() == Token::kCOMMA) {
ConsumeToken();
message_pos = TokenPos();
message = ParseExpr(kAllowConst, kConsumeCascades);
diff --git a/runtime/vm/precompiler.cc b/runtime/vm/precompiler.cc
index e2eb627..e45c04c 100644
--- a/runtime/vm/precompiler.cc
+++ b/runtime/vm/precompiler.cc
@@ -33,6 +33,7 @@
#include "vm/object_store.h"
#include "vm/os.h"
#include "vm/parser.h"
+#include "vm/program_visitor.h"
#include "vm/redundancy_elimination.h"
#include "vm/regexp_assembler.h"
#include "vm/regexp_parser.h"
@@ -42,10 +43,11 @@
#include "vm/timeline.h"
#include "vm/timer.h"
#include "vm/type_table.h"
+#include "vm/version.h"
+#include "vm/json_parser.h"
namespace dart {
-
#define T (thread())
#define I (isolate())
#define Z (zone())
@@ -76,6 +78,15 @@
DECLARE_FLAG(bool, trace_failed_optimization_attempts);
DECLARE_FLAG(bool, trace_inlining_intervals);
DECLARE_FLAG(bool, trace_irregexp);
+DECLARE_FLAG(int, inlining_hotness);
+DECLARE_FLAG(int, inlining_size_threshold);
+DECLARE_FLAG(int, inlining_callee_size_threshold);
+DECLARE_FLAG(int, inline_getters_setters_smaller_than);
+DECLARE_FLAG(int, inlining_depth_threshold);
+DECLARE_FLAG(int, inlining_caller_size_threshold);
+DECLARE_FLAG(int, inlining_constant_arguments_max_size_threshold);
+DECLARE_FLAG(int, inlining_constant_arguments_min_size_threshold);
+
#ifdef DART_PRECOMPILER
@@ -185,12 +196,37 @@
}
+TypeRangeCache::TypeRangeCache(Precompiler* precompiler,
+ Thread* thread,
+ intptr_t num_cids)
+ : precompiler_(precompiler),
+ thread_(thread),
+ lower_limits_(thread->zone()->Alloc<intptr_t>(num_cids)),
+ upper_limits_(thread->zone()->Alloc<intptr_t>(num_cids)) {
+ for (intptr_t i = 0; i < num_cids; i++) {
+ lower_limits_[i] = kNotComputed;
+ upper_limits_[i] = kNotComputed;
+ }
+ ASSERT(precompiler->type_range_cache() == NULL);
+ precompiler->set_type_range_cache(this);
+}
+
+
+TypeRangeCache::~TypeRangeCache() {
+ ASSERT(precompiler_->type_range_cache() == this);
+ precompiler_->set_type_range_cache(NULL);
+}
+
+
RawError* Precompiler::CompileAll(
Dart_QualifiedFunctionName embedder_entry_points[],
- bool reset_fields) {
+ bool reset_fields,
+ uint8_t* jit_feedback,
+ intptr_t jit_feedback_length) {
LongJumpScope jump;
if (setjmp(*jump.Set()) == 0) {
Precompiler precompiler(Thread::Current(), reset_fields);
+ precompiler.LoadFeedback(jit_feedback, jit_feedback_length);
precompiler.DoCompileAll(embedder_entry_points);
return Error::null();
} else {
@@ -294,6 +330,7 @@
zone_(NULL),
isolate_(thread->isolate()),
reset_fields_(reset_fields),
+ jit_feedback_(NULL),
changed_(false),
function_count_(0),
class_count_(0),
@@ -316,10 +353,52 @@
types_to_retain_(),
consts_to_retain_(),
field_type_map_(),
+ type_range_cache_(NULL),
error_(Error::Handle()),
get_runtime_type_is_unique_(false) {}
+void Precompiler::LoadFeedback(uint8_t* buffer, intptr_t length) {
+ if (buffer == NULL) {
+ if (FLAG_trace_precompiler) {
+ THR_Print("Precompiler running without JIT feedback\n");
+ }
+
+ // Flags affecting compilation only:
+ // There is no counter feedback in precompilation, so ignore the counter
+ // when making inlining decisions.
+ FLAG_inlining_hotness = 0;
+ // Use smaller thresholds in precompilation as we are compiling everything
+ // with the optimizing compiler instead of only hot functions.
+ FLAG_inlining_size_threshold = 5;
+ FLAG_inline_getters_setters_smaller_than = 5;
+ FLAG_inlining_callee_size_threshold = 20;
+ FLAG_inlining_depth_threshold = 4;
+ FLAG_inlining_caller_size_threshold = 1000;
+ FLAG_inlining_constant_arguments_max_size_threshold = 100;
+ FLAG_inlining_constant_arguments_min_size_threshold = 30;
+ return;
+ }
+
+ if (FLAG_trace_precompiler) {
+ THR_Print("Loading JIT feedback\n");
+ }
+
+ JSONParser parser(reinterpret_cast<const char*>(buffer), length,
+ Thread::Current()->zone());
+ ParsedJSONValue* root = parser.ParseValue();
+ if (root->IsError()) {
+ ParsedJSONError* error = static_cast<ParsedJSONError*>(root);
+ THR_Print("Error parsing JIT feedback: %s:%" Pd "\n", error->message(),
+ error->position());
+ } else if (!root->IsObject()) {
+ THR_Print("Error parsing JIT feedback: object expected\n");
+ } else {
+ jit_feedback_ = static_cast<ParsedJSONObject*>(root);
+ }
+}
+
+
void Precompiler::DoCompileAll(
Dart_QualifiedFunctionName embedder_entry_points[]) {
ASSERT(I->compilation_allowed());
@@ -336,7 +415,8 @@
FinalizeAllClasses();
SortClasses();
- TypeRangeCache trc(T, I->class_table()->NumCids());
+ TypeRangeCache trc(this, T, I->class_table()->NumCids());
+ VerifyJITFeedback();
// Precompile static initializers to compute result type information.
PrecompileStaticInitializers();
@@ -478,7 +558,7 @@
HANDLESCOPE(T);
StaticInitializerVisitor visitor(Z);
- VisitClasses(&visitor);
+ ProgramVisitor::VisitClasses(&visitor);
}
@@ -508,7 +588,7 @@
HANDLESCOPE(T);
ConstructorVisitor visitor(this, zone_);
- VisitFunctions(&visitor);
+ ProgramVisitor::VisitFunctions(&visitor);
FieldTypeMap::Iterator it(field_type_map_.GetIterator());
for (FieldTypePair* current = it.Next(); current != NULL;
@@ -533,13 +613,13 @@
}
};
ClearCodeFunctionVisitor function_visitor;
- VisitFunctions(&function_visitor);
+ ProgramVisitor::VisitFunctions(&function_visitor);
class ClearCodeClassVisitor : public ClassVisitor {
void Visit(const Class& cls) { cls.DisableAllocationStub(); }
};
ClearCodeClassVisitor class_visitor;
- VisitClasses(&class_visitor);
+ ProgramVisitor::VisitClasses(&class_visitor);
}
@@ -2081,7 +2161,7 @@
};
BindStaticCallsVisitor visitor(Z);
- VisitFunctions(&visitor);
+ ProgramVisitor::VisitFunctions(&visitor);
}
@@ -2170,7 +2250,7 @@
ASSERT(!I->compilation_allowed());
SwitchICCallsVisitor visitor(Z);
- VisitFunctions(&visitor);
+ ProgramVisitor::VisitFunctions(&visitor);
#endif
}
@@ -2243,7 +2323,7 @@
};
DedupStackMapsVisitor visitor(Z);
- VisitFunctions(&visitor);
+ ProgramVisitor::VisitFunctions(&visitor);
}
@@ -2310,7 +2390,7 @@
};
DedupListsVisitor visitor(Z);
- VisitFunctions(&visitor);
+ ProgramVisitor::VisitFunctions(&visitor);
}
@@ -2356,81 +2436,7 @@
};
DedupInstructionsVisitor visitor(Z);
- VisitFunctions(&visitor);
-}
-
-
-void Precompiler::VisitClasses(ClassVisitor* visitor) {
- Library& lib = Library::Handle(Z);
- Class& cls = Class::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.
- }
- visitor->Visit(cls);
- }
- }
-}
-
-
-void Precompiler::VisitFunctions(FunctionVisitor* visitor) {
- 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);
-
- 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.
- }
-
- functions = cls.functions();
- for (intptr_t j = 0; j < functions.Length(); j++) {
- function ^= functions.At(j);
- visitor->Visit(function);
- if (function.HasImplicitClosureFunction()) {
- function = function.ImplicitClosureFunction();
- visitor->Visit(function);
- }
- }
-
- functions = cls.invocation_dispatcher_cache();
- for (intptr_t j = 0; j < functions.Length(); j++) {
- object = functions.At(j);
- if (object.IsFunction()) {
- function ^= functions.At(j);
- visitor->Visit(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->Visit(function);
- }
- }
- }
- }
- closures = isolate()->object_store()->closure_functions();
- for (intptr_t j = 0; j < closures.Length(); j++) {
- function ^= closures.At(j);
- visitor->Visit(function);
- ASSERT(!function.HasImplicitClosureFunction());
- }
+ ProgramVisitor::VisitFunctions(&visitor);
}
@@ -2607,6 +2613,342 @@
}
+void Precompiler::VerifyJITFeedback() {
+ if (jit_feedback_ == NULL) return;
+
+ ParsedJSONString* js_vmversion = jit_feedback_->StringAt("vmVersion");
+ if ((js_vmversion == NULL) ||
+ strcmp(js_vmversion->value(), Version::CommitString()) != 0) {
+ THR_Print(
+ "JIT feedback contains invalid vm version "
+ "(saw %s, expected %s).\n",
+ js_vmversion->value(), Version::CommitString());
+ jit_feedback_ = NULL;
+ return;
+ }
+ ParsedJSONBoolean* js_asserts = jit_feedback_->BooleanAt("asserts");
+ if ((js_asserts == NULL) || (FLAG_enable_asserts != js_asserts->value())) {
+ THR_Print("JIT feedback contains invalid FLAG_enable_asserts\n");
+ jit_feedback_ = NULL;
+ return;
+ }
+ ParsedJSONBoolean* js_typechecks = jit_feedback_->BooleanAt("typeChecks");
+ if ((js_typechecks == NULL) ||
+ (FLAG_enable_type_checks != js_typechecks->value())) {
+ THR_Print("JIT feedback contains invalid FLAG_enable_type_checks\n");
+ jit_feedback_ = NULL;
+ return;
+ }
+
+ ParsedJSONArray* js_scripts = jit_feedback_->ArrayAt("scripts");
+ ASSERT(js_scripts != NULL);
+ Script& script = Script::Handle(Z);
+ for (intptr_t i = 0; i < js_scripts->Length(); i++) {
+ ParsedJSONObject* js_script = js_scripts->ObjectAt(i);
+ ASSERT(js_script != NULL);
+ ParsedJSONString* js_uri = js_script->StringAt("uri");
+ ASSERT(js_uri != NULL);
+ ParsedJSONNumber* js_fp = js_script->NumberAt("checksum");
+ ASSERT(js_fp != NULL);
+ script = LookupScript(js_uri->value());
+ if (script.IsNull()) {
+ THR_Print("Cannot find script %s\n", js_uri->value());
+ continue;
+ }
+ intptr_t fp = script.SourceFingerprint();
+ if (fp != js_fp->value()) {
+ THR_Print(
+ "Fingerprint has changed for %s. Continuing without JIT "
+ "feedback.\n",
+ js_uri->value());
+ jit_feedback_ = NULL;
+ return;
+ }
+ }
+
+ ParsedJSONArray* js_classes = jit_feedback_->ArrayAt("classes");
+ ASSERT(js_classes != NULL);
+ Library& lib = Library::Handle(Z);
+ Class& cls = Class::Handle(Z);
+ String& str = String::Handle(Z);
+ for (intptr_t i = 0; i < js_classes->Length(); i++) {
+ ParsedJSONObject* js_class = js_classes->ObjectAt(i);
+ ASSERT(js_class != NULL);
+ ParsedJSONString* js_uri = js_class->StringAt("uri");
+ ASSERT(js_uri != NULL);
+ ParsedJSONString* js_name = js_class->StringAt("name");
+ ASSERT(js_name != NULL);
+ ParsedJSONNumber* js_cid = js_class->NumberAt("cid");
+ ASSERT(js_cid != NULL);
+
+ str = String::New(js_uri->value());
+ lib = Library::LookupLibrary(T, str);
+ if (lib.IsNull()) {
+ THR_Print("Cannot find library %s\n", js_uri->value());
+ continue;
+ }
+ str = String::New(js_name->value());
+ if (str.Equals(Symbols::TopLevel())) {
+ cls = lib.toplevel_class();
+ } else {
+ cls = lib.LookupClassAllowPrivate(str);
+ }
+ if (cls.IsNull()) {
+ THR_Print("Missing class %s\n", js_name->value());
+ continue;
+ }
+
+ feedback_cid_map_.Insert(IntptrPair(js_cid->value(), cls.id()));
+ }
+
+ ParsedJSONArray* js_functions = jit_feedback_->ArrayAt("functions");
+ ASSERT(js_functions != NULL);
+ for (intptr_t i = 0; i < js_functions->Length(); i++) {
+ ParsedJSONObject* js_function = js_functions->ObjectAt(i);
+ ASSERT(js_function != NULL);
+ ParsedJSONString* js_name = js_function->StringAt("name");
+ ASSERT(js_name != NULL);
+ ParsedJSONNumber* js_cid = js_function->NumberAt("class");
+ ASSERT(js_cid != NULL);
+ ParsedJSONNumber* js_token = js_function->NumberAt("tokenPos");
+ ASSERT(js_token != NULL);
+ ParsedJSONNumber* js_kind = js_function->NumberAt("kind");
+ ASSERT(js_kind != NULL);
+ function_feedback_map_.Insert(FunctionFeedbackPair(
+ FunctionFeedbackKey(MapCid(js_cid->value()), js_token->value(),
+ js_kind->value()),
+ js_function));
+ }
+
+ class ApplyUsageVisitor : public FunctionVisitor {
+ public:
+ explicit ApplyUsageVisitor(Precompiler* precompiler)
+ : precompiler_(precompiler) {}
+ void Visit(const Function& function) {
+ ParsedJSONObject* js_function = precompiler_->LookupFeedback(function);
+ if (js_function == NULL) {
+ function.set_usage_counter(0);
+ } else {
+ ParsedJSONNumber* js_usage = js_function->NumberAt("usageCounter");
+ ASSERT(js_usage != NULL);
+ function.set_usage_counter(js_usage->value());
+ }
+ }
+
+ private:
+ Precompiler* precompiler_;
+ };
+
+ ApplyUsageVisitor visitor(this);
+ ProgramVisitor::VisitFunctions(&visitor);
+}
+
+
+ParsedJSONObject* Precompiler::LookupFeedback(const Function& function) {
+ const Class& owner = Class::Handle(Z, function.Owner());
+
+ FunctionFeedbackKey key(owner.id(), function.token_pos().value(),
+ function.kind());
+ FunctionFeedbackPair* pair = function_feedback_map_.Lookup(key);
+ if (pair == NULL) {
+ return NULL;
+ }
+ return pair->value_;
+}
+
+
+RawScript* Precompiler::LookupScript(const char* uri) {
+ String& dart_uri = String::Handle(Z, String::New(uri));
+ Library& lib = Library::Handle(Z);
+ Script& script = Script::Handle(Z);
+ for (intptr_t i = 0; i < libraries_.Length(); i++) {
+ lib ^= libraries_.At(i);
+ script = lib.LookupScript(dart_uri);
+ if (!script.IsNull()) {
+ return script.raw();
+ }
+ }
+ return Script::null();
+}
+
+
+intptr_t Precompiler::MapCid(intptr_t feedback_cid) {
+ if (feedback_cid < kNumPredefinedCids) {
+ return feedback_cid;
+ }
+ IntptrPair* pair = feedback_cid_map_.Lookup(feedback_cid);
+ if (pair == NULL) return kIllegalCid;
+ return pair->value_;
+}
+
+
+void Precompiler::PopulateWithICData(const Function& function,
+ FlowGraph* graph) {
+ Zone* zone = Thread::Current()->zone();
+
+ for (BlockIterator block_it = graph->reverse_postorder_iterator();
+ !block_it.Done(); block_it.Advance()) {
+ ForwardInstructionIterator it(block_it.Current());
+ for (; !it.Done(); it.Advance()) {
+ Instruction* instr = it.Current();
+ if (instr->IsInstanceCall()) {
+ InstanceCallInstr* call = instr->AsInstanceCall();
+ if (!call->HasICData()) {
+ const Array& arguments_descriptor = Array::Handle(
+ zone, ArgumentsDescriptor::New(call->ArgumentCount(),
+ call->argument_names()));
+ const ICData& ic_data = ICData::ZoneHandle(
+ zone, ICData::New(function, call->function_name(),
+ arguments_descriptor, call->deopt_id(),
+ call->checked_argument_count(), false));
+ call->set_ic_data(&ic_data);
+ }
+ } else if (instr->IsStaticCall()) {
+ StaticCallInstr* call = instr->AsStaticCall();
+ if (!call->HasICData()) {
+ const Array& arguments_descriptor = Array::Handle(
+ zone, ArgumentsDescriptor::New(call->ArgumentCount(),
+ call->argument_names()));
+ const Function& target = call->function();
+ MethodRecognizer::Kind recognized_kind =
+ MethodRecognizer::RecognizeKind(target);
+ int num_args_checked = 0;
+ switch (recognized_kind) {
+ case MethodRecognizer::kDoubleFromInteger:
+ case MethodRecognizer::kMathMin:
+ case MethodRecognizer::kMathMax:
+ num_args_checked = 2;
+ break;
+ default:
+ break;
+ }
+ const ICData& ic_data = ICData::ZoneHandle(
+ zone, ICData::New(function, String::Handle(zone, target.name()),
+ arguments_descriptor, call->deopt_id(),
+ num_args_checked, true));
+ ic_data.AddTarget(target);
+ call->set_ic_data(&ic_data);
+ }
+ }
+ }
+ }
+}
+
+
+void Precompiler::TryApplyFeedback(const Function& function, FlowGraph* graph) {
+ ParsedJSONObject* js_function = LookupFeedback(function);
+ if (js_function == NULL) {
+ if (FLAG_trace_precompiler) {
+ THR_Print("No feedback available for %s\n",
+ function.ToQualifiedCString());
+ }
+ return;
+ }
+
+ ParsedJSONArray* js_icdatas = js_function->ArrayAt("ics");
+ ASSERT(js_icdatas != NULL);
+
+ for (BlockIterator block_it = graph->reverse_postorder_iterator();
+ !block_it.Done(); block_it.Advance()) {
+ ForwardInstructionIterator it(block_it.Current());
+ for (; !it.Done(); it.Advance()) {
+ Instruction* instr = it.Current();
+ if (instr->IsInstanceCall()) {
+ InstanceCallInstr* call = instr->AsInstanceCall();
+ TryApplyFeedback(js_icdatas, *call->ic_data());
+ } else if (instr->IsStaticCall()) {
+ StaticCallInstr* call = instr->AsStaticCall();
+ TryApplyFeedback(js_icdatas, *call->ic_data());
+ }
+ }
+ }
+}
+
+
+void Precompiler::TryApplyFeedback(ParsedJSONArray* js_icdatas,
+ const ICData& ic) {
+ for (intptr_t j = 0; j < js_icdatas->Length(); j++) {
+ ParsedJSONObject* js_icdata = js_icdatas->ObjectAt(j);
+ ASSERT(js_icdata != NULL);
+
+ ParsedJSONNumber* js_deoptid = js_icdata->NumberAt("deoptId");
+ ASSERT(js_deoptid != NULL);
+ if (js_deoptid->value() != ic.deopt_id()) continue;
+
+ ParsedJSONBoolean* js_isstaticcall = js_icdata->BooleanAt("isStaticCall");
+ ASSERT(js_isstaticcall != NULL);
+ if (js_isstaticcall->value() != ic.is_static_call()) return;
+
+ ParsedJSONNumber* js_argsTested = js_icdata->NumberAt("argsTested");
+ ASSERT(js_argsTested != NULL);
+ if (js_argsTested->value() != ic.NumArgsTested()) return;
+
+ ParsedJSONString* js_selector = js_icdata->StringAt("selector");
+ ASSERT(js_selector != NULL);
+ const String& feedback_selector =
+ String::Handle(String::New(js_selector->value()));
+ const String& selector = String::Handle(ic.target_name());
+ // N.B.: EqualsIgnoringPrivateKey is not symmetric.
+ if (!String::EqualsIgnoringPrivateKey(selector, feedback_selector)) return;
+
+ ParsedJSONArray* js_entries = js_icdata->ArrayAt("entries");
+ ASSERT(js_entries != NULL);
+ if (ic.is_static_call()) {
+ // [cid [cid]] target count
+ ParsedJSONNumber* entry = js_entries->NumberAt(js_entries->Length() - 1);
+ ASSERT(entry != NULL);
+ ic.SetCountAt(0, entry->value());
+ } else {
+ // [cid [cid [cid]]] target count
+ const Array& arguments_descriptor =
+ Array::Handle(ic.arguments_descriptor());
+ ArgumentsDescriptor args_desc(arguments_descriptor);
+
+ intptr_t num_args_checked = ic.NumArgsTested();
+ for (intptr_t k = 0; k < js_entries->Length();
+ k += num_args_checked + 1) {
+ GrowableArray<intptr_t> class_ids(num_args_checked);
+ for (intptr_t arg = 0; arg < num_args_checked; arg++) {
+ ParsedJSONNumber* entry = js_entries->NumberAt(k + arg);
+ ASSERT(entry != NULL);
+ class_ids.Add(MapCid(entry->value()));
+ }
+ ParsedJSONNumber* entry = js_entries->NumberAt(k + num_args_checked);
+ ASSERT(entry != NULL);
+ intptr_t count = entry->value();
+
+ bool has_missing_cid = false;
+ for (intptr_t arg = 0; arg < num_args_checked; arg++) {
+ if (class_ids[arg] == kIllegalCid) {
+ has_missing_cid = true;
+ }
+ }
+ if (has_missing_cid) continue;
+
+ intptr_t receiver_cid = class_ids[0];
+ const Class& receiver_cls =
+ Class::Handle(I->class_table()->At(receiver_cid));
+ if (receiver_cls.IsClass()) {
+ const Function& target =
+ Function::Handle(Resolver::ResolveDynamicForReceiverClass(
+ receiver_cls, selector, args_desc, false));
+ // TODO(rmacnak): Create missing dispatchers.
+ if (!target.IsNull()) {
+ if (num_args_checked == 1) {
+ ic.AddReceiverCheck(receiver_cid, target, count);
+ } else {
+ ic.AddCheck(class_ids, target, count);
+ }
+ }
+ }
+ }
+ }
+
+ return;
+ }
+}
+
+
void Precompiler::ResetPrecompilerState() {
changed_ = false;
function_count_ = 0;
@@ -2757,6 +3099,15 @@
zone, parsed_function(), *ic_data_array, Compiler::kNoOSRDeoptId);
}
+ if (optimized()) {
+ Precompiler::PopulateWithICData(parsed_function()->function(),
+ flow_graph);
+ if (precompiler_ != NULL) {
+ precompiler_->TryApplyFeedback(parsed_function()->function(),
+ flow_graph);
+ }
+ }
+
const bool print_flow_graph =
(FLAG_print_flow_graph ||
(optimized() && FLAG_print_flow_graph_optimized)) &&
@@ -2807,7 +3158,6 @@
AotOptimizer optimizer(precompiler_, flow_graph,
use_speculative_inlining, &inlining_black_list);
- optimizer.PopulateWithICData();
optimizer.ApplyClassIds();
DEBUG_ASSERT(flow_graph->VerifyUseLists());
diff --git a/runtime/vm/precompiler.h b/runtime/vm/precompiler.h
index b763363..f4af735 100644
--- a/runtime/vm/precompiler.h
+++ b/runtime/vm/precompiler.h
@@ -21,28 +21,15 @@
class RawError;
class SequenceNode;
class String;
+class ParsedJSONObject;
+class ParsedJSONArray;
+class Precompiler;
+class FlowGraph;
-
-class TypeRangeCache : public StackResource {
+class TypeRangeCache : public ValueObject {
public:
- TypeRangeCache(Thread* thread, intptr_t num_cids)
- : StackResource(thread),
- thread_(thread),
- lower_limits_(thread->zone()->Alloc<intptr_t>(num_cids)),
- upper_limits_(thread->zone()->Alloc<intptr_t>(num_cids)) {
- for (intptr_t i = 0; i < num_cids; i++) {
- lower_limits_[i] = kNotComputed;
- upper_limits_[i] = kNotComputed;
- }
- // We don't re-enter the precompiler.
- ASSERT(thread->type_range_cache() == NULL);
- thread->set_type_range_cache(this);
- }
-
- ~TypeRangeCache() {
- ASSERT(thread_->type_range_cache() == this);
- thread_->set_type_range_cache(NULL);
- }
+ TypeRangeCache(Precompiler* precompiler, Thread* thread, intptr_t num_cids);
+ ~TypeRangeCache();
bool InstanceOfHasClassRange(const AbstractType& type,
intptr_t* lower_limit,
@@ -52,6 +39,7 @@
static const intptr_t kNotComputed = -1;
static const intptr_t kNotContiguous = -2;
+ Precompiler* precompiler_;
Thread* thread_;
intptr_t* lower_limits_;
intptr_t* upper_limits_;
@@ -328,11 +316,79 @@
typedef DirectChainedHashMap<FieldTypePair> FieldTypeMap;
+struct IntptrPair {
+ // Typedefs needed for the DirectChainedHashMap template.
+ typedef intptr_t Key;
+ typedef intptr_t Value;
+ typedef IntptrPair Pair;
+
+ static Key KeyOf(Pair kv) { return kv.key_; }
+
+ static Value ValueOf(Pair kv) { return kv.value_; }
+
+ static inline intptr_t Hashcode(Key key) { return key; }
+
+ static inline bool IsKeyEqual(Pair pair, Key key) { return pair.key_ == key; }
+
+ IntptrPair(intptr_t key, intptr_t value) : key_(key), value_(value) {}
+
+ IntptrPair() : key_(kIllegalCid), value_(kIllegalCid) {}
+
+ Key key_;
+ Value value_;
+};
+
+typedef DirectChainedHashMap<IntptrPair> CidMap;
+
+
+struct FunctionFeedbackKey {
+ FunctionFeedbackKey() : owner_cid_(kIllegalCid), token_(0), kind_(0) {}
+ FunctionFeedbackKey(intptr_t owner_cid, intptr_t token, intptr_t kind)
+ : owner_cid_(owner_cid), token_(token), kind_(kind) {}
+
+ intptr_t owner_cid_;
+ intptr_t token_;
+ intptr_t kind_;
+};
+
+
+struct FunctionFeedbackPair {
+ // Typedefs needed for the DirectChainedHashMap template.
+ typedef FunctionFeedbackKey Key;
+ typedef ParsedJSONObject* Value;
+ typedef FunctionFeedbackPair Pair;
+
+ static Key KeyOf(Pair kv) { return kv.key_; }
+
+ static Value ValueOf(Pair kv) { return kv.value_; }
+
+ static inline intptr_t Hashcode(Key key) {
+ return key.token_ ^ key.owner_cid_ ^ key.kind_;
+ }
+
+ static inline bool IsKeyEqual(Pair pair, Key key) {
+ return (pair.key_.owner_cid_ == key.owner_cid_) &&
+ (pair.key_.token_ == key.token_) && (pair.key_.kind_ == key.kind_);
+ }
+
+ FunctionFeedbackPair(Key key, Value value) : key_(key), value_(value) {}
+
+ FunctionFeedbackPair() : key_(), value_(NULL) {}
+
+ Key key_;
+ Value value_;
+};
+
+typedef DirectChainedHashMap<FunctionFeedbackPair> FunctionFeedbackMap;
+
+
class Precompiler : public ValueObject {
public:
static RawError* CompileAll(
Dart_QualifiedFunctionName embedder_entry_points[],
- bool reset_fields);
+ bool reset_fields,
+ uint8_t* jit_feedback,
+ intptr_t jit_feedback_length);
static RawError* CompileFunction(Precompiler* precompiler,
Thread* thread,
@@ -352,10 +408,22 @@
}
FieldTypeMap* field_type_map() { return &field_type_map_; }
+ TypeRangeCache* type_range_cache() { return type_range_cache_; }
+ void set_type_range_cache(TypeRangeCache* value) {
+ type_range_cache_ = value;
+ }
+
+ bool HasFeedback() const { return jit_feedback_ != NULL; }
+ static void PopulateWithICData(const Function& func, FlowGraph* graph);
+ void TryApplyFeedback(const Function& func, FlowGraph* graph);
+ void TryApplyFeedback(ParsedJSONArray* js_icdatas, const ICData& ic);
private:
Precompiler(Thread* thread, bool reset_fields);
+ void LoadFeedback(uint8_t* jit_feedback, intptr_t jit_feedback_length);
+ ParsedJSONObject* LookupFeedback(const Function& function);
+
void DoCompileAll(Dart_QualifiedFunctionName embedder_entry_points[]);
void ClearAllCode();
void AddRoots(Dart_QualifiedFunctionName embedder_entry_points[]);
@@ -403,21 +471,12 @@
void PrecompileStaticInitializers();
void PrecompileConstructors();
- template <typename T>
- class Visitor : public ValueObject {
- public:
- virtual ~Visitor() {}
- virtual void Visit(const T& obj) = 0;
- };
- typedef Visitor<Function> FunctionVisitor;
- typedef Visitor<Class> ClassVisitor;
-
- void VisitFunctions(FunctionVisitor* visitor);
- void VisitClasses(ClassVisitor* visitor);
-
void FinalizeAllClasses();
void SortClasses();
void RemapClassIds(intptr_t* old_to_new_cid);
+ void VerifyJITFeedback();
+ RawScript* LookupScript(const char* uri);
+ intptr_t MapCid(intptr_t feedback_cid);
Thread* thread() const { return thread_; }
Zone* zone() const { return zone_; }
@@ -429,6 +488,8 @@
const bool reset_fields_;
+ ParsedJSONObject* jit_feedback_;
+
bool changed_;
intptr_t function_count_;
intptr_t class_count_;
@@ -451,6 +512,9 @@
AbstractTypeSet types_to_retain_;
InstanceSet consts_to_retain_;
FieldTypeMap field_type_map_;
+ TypeRangeCache* type_range_cache_;
+ CidMap feedback_cid_map_;
+ FunctionFeedbackMap function_feedback_map_;
Error& error_;
bool get_runtime_type_is_unique_;
diff --git a/runtime/vm/program_visitor.cc b/runtime/vm/program_visitor.cc
new file mode 100644
index 0000000..4a41925
--- /dev/null
+++ b/runtime/vm/program_visitor.cc
@@ -0,0 +1,95 @@
+// Copyright (c) 2015, 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 "vm/program_visitor.h"
+
+#include "vm/object.h"
+#include "vm/object_store.h"
+
+namespace dart {
+
+void ProgramVisitor::VisitClasses(ClassVisitor* visitor) {
+ Thread* thread = Thread::Current();
+ Isolate* isolate = thread->isolate();
+ Zone* zone = thread->zone();
+ GrowableObjectArray& libraries =
+ GrowableObjectArray::Handle(zone, isolate->object_store()->libraries());
+ Library& lib = Library::Handle(zone);
+ Class& cls = Class::Handle(zone);
+
+ 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.
+ }
+ visitor->Visit(cls);
+ }
+ }
+}
+
+
+void ProgramVisitor::VisitFunctions(FunctionVisitor* visitor) {
+ Thread* thread = Thread::Current();
+ Isolate* isolate = thread->isolate();
+ Zone* zone = thread->zone();
+ GrowableObjectArray& libraries =
+ GrowableObjectArray::Handle(zone, isolate->object_store()->libraries());
+ Library& lib = Library::Handle(zone);
+ Class& cls = Class::Handle(zone);
+ Array& functions = Array::Handle(zone);
+ Array& fields = Array::Handle(zone);
+ Field& field = Field::Handle(zone);
+ Object& object = Object::Handle(zone);
+ Function& function = Function::Handle(zone);
+ GrowableObjectArray& closures = GrowableObjectArray::Handle(zone);
+
+ 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.
+ }
+
+ functions = cls.functions();
+ for (intptr_t j = 0; j < functions.Length(); j++) {
+ function ^= functions.At(j);
+ visitor->Visit(function);
+ if (function.HasImplicitClosureFunction()) {
+ function = function.ImplicitClosureFunction();
+ visitor->Visit(function);
+ }
+ }
+
+ functions = cls.invocation_dispatcher_cache();
+ for (intptr_t j = 0; j < functions.Length(); j++) {
+ object = functions.At(j);
+ if (object.IsFunction()) {
+ function ^= functions.At(j);
+ visitor->Visit(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->Visit(function);
+ }
+ }
+ }
+ }
+ closures = isolate->object_store()->closure_functions();
+ for (intptr_t j = 0; j < closures.Length(); j++) {
+ function ^= closures.At(j);
+ visitor->Visit(function);
+ ASSERT(!function.HasImplicitClosureFunction());
+ }
+}
+
+} // namespace dart
diff --git a/runtime/vm/program_visitor.h b/runtime/vm/program_visitor.h
new file mode 100644
index 0000000..5ac8130
--- /dev/null
+++ b/runtime/vm/program_visitor.h
@@ -0,0 +1,33 @@
+// Copyright (c) 2015, 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.
+
+#ifndef RUNTIME_VM_PROGRAM_VISITOR_H_
+#define RUNTIME_VM_PROGRAM_VISITOR_H_
+
+#include "vm/allocation.h"
+
+namespace dart {
+
+class Function;
+class Class;
+
+template <typename T>
+class Visitor : public ValueObject {
+ public:
+ virtual ~Visitor() {}
+ virtual void Visit(const T& obj) = 0;
+};
+
+typedef Visitor<Function> FunctionVisitor;
+typedef Visitor<Class> ClassVisitor;
+
+class ProgramVisitor : public AllStatic {
+ public:
+ static void VisitFunctions(FunctionVisitor* visitor);
+ static void VisitClasses(ClassVisitor* visitor);
+};
+
+} // namespace dart
+
+#endif // RUNTIME_VM_PROGRAM_VISITOR_H_
diff --git a/runtime/vm/simulator_dbc.cc b/runtime/vm/simulator_dbc.cc
index dea082a..b114dc6 100644
--- a/runtime/vm/simulator_dbc.cc
+++ b/runtime/vm/simulator_dbc.cc
@@ -3554,19 +3554,13 @@
{
BYTECODE(Deopt, A_D);
+
+ // Note: frame translation will take care of preserving result at the
+ // top of the stack. See CompilerDeoptInfo::CreateDeoptInfo.
const bool is_lazy = rD == 0;
- // Preserve result of the previous call.
- // TODO(vegorov) we could have actually included result into the
- // deoptimization environment because it is passed through the stack.
- // If we do then we could remove special result handling from this code.
- RawObject* result = SP[0];
-
- // When not preserving the result, we still need to preserve SP[0] as it
- // contains some temporary expression.
- if (!is_lazy) {
- SP++;
- }
+ // Make sure we preserve SP[0] when entering synthetic frame below.
+ SP++;
// Leaf runtime function DeoptimizeCopyFrame expects a Dart frame.
// The code in this frame may not cause GC.
@@ -3582,9 +3576,6 @@
// We are now inside a valid frame.
{
- if (is_lazy) {
- *++SP = result; // Preserve result (call below can cause GC).
- }
*++SP = 0; // Space for the result: number of materialization args.
Exit(thread, FP, SP + 1, /*pc=*/0);
NativeArguments native_args(thread, 0, SP, SP);
@@ -3592,10 +3583,6 @@
}
const intptr_t materialization_arg_count =
Smi::Value(RAW_CAST(Smi, *SP--)) / kWordSize;
- if (is_lazy) {
- // Reload the result. It might have been relocated by GC.
- result = *SP--;
- }
// Restore caller PC.
pc = SavedCallerPC(FP);
@@ -3604,21 +3591,13 @@
// Check if it is a fake PC marking the entry frame.
ASSERT((reinterpret_cast<uword>(pc) & 2) == 0);
- // Restore SP, FP and PP. Push result and dispatch.
- // Note: unlike in a normal return sequence we don't need to drop
- // arguments - those are not part of the innermost deoptimization
- // environment they were dropped by FlowGraphCompiler::RecordAfterCall.
-
- // If the result is not preserved, the unoptimized frame ends at the
- // next slot.
- SP = FrameArguments(FP, materialization_arg_count);
+ // Restore SP, FP and PP.
+ // Unoptimized frame SP is one below FrameArguments(...) because
+ // FrameArguments(...) returns a pointer to the first argument.
+ SP = FrameArguments(FP, materialization_arg_count) - 1;
FP = SavedCallerFP(FP);
pp = SimulatorHelpers::FrameCode(FP)->ptr()->object_pool_->ptr();
- if (is_lazy) {
- SP[0] = result; // Put the result on the stack.
- } else {
- SP--; // No result to push.
- }
+
DISPATCH();
}
diff --git a/runtime/vm/snapshot_test.cc b/runtime/vm/snapshot_test.cc
index 81c4342..79b5b1b 100644
--- a/runtime/vm/snapshot_test.cc
+++ b/runtime/vm/snapshot_test.cc
@@ -1399,47 +1399,6 @@
Dart_ExitScope();
Dart_ShutdownIsolate();
}
- free(script_snapshot);
-
- // Test for Dart_CreateLibrarySnapshot.
- {
- // Create an Isolate using the full snapshot, load a script and create
- // a script snapshot of the script.
- TestCase::CreateTestIsolateFromSnapshot(full_snapshot);
- Dart_EnterScope(); // Start a Dart API scope for invoking API functions.
-
- // Load the library.
- Dart_Handle lib = Dart_LoadLibrary(NewString("dart_lib"), Dart_Null(),
- NewString(kScriptChars), 0, 0);
- EXPECT_VALID(lib);
-
- // Write out the script snapshot.
- result = Dart_CreateLibrarySnapshot(lib, &buffer, &size);
- EXPECT_VALID(result);
- script_snapshot = reinterpret_cast<uint8_t*>(malloc(size));
- memmove(script_snapshot, buffer, size);
- Dart_ExitScope();
- Dart_ShutdownIsolate();
- }
-
- {
- // Now Create an Isolate using the full snapshot and load the
- // script snapshot created above and execute it.
- TestCase::CreateTestIsolateFromSnapshot(full_snapshot);
- Dart_EnterScope(); // Start a Dart API scope for invoking API functions.
-
- // Load the test library from the snapshot.
- EXPECT(script_snapshot != NULL);
- result = Dart_LoadScriptFromSnapshot(script_snapshot, size);
- EXPECT_VALID(result);
-
- // Invoke a function which returns an object.
- Dart_Handle cls = Dart_GetClass(result, NewString("FieldsTest"));
- result = Dart_Invoke(cls, NewString("testMain"), 0, NULL);
- EXPECT_VALID(result);
- Dart_ExitScope();
- Dart_ShutdownIsolate();
- }
free(full_snapshot);
free(script_snapshot);
}
diff --git a/runtime/vm/stub_code.cc b/runtime/vm/stub_code.cc
index 5b6a5f5..cf77f5f 100644
--- a/runtime/vm/stub_code.cc
+++ b/runtime/vm/stub_code.cc
@@ -20,9 +20,11 @@
DEFINE_FLAG(bool, disassemble_stubs, false, "Disassemble generated stubs.");
-#define STUB_CODE_DECLARE(name) StubEntry* StubCode::name##_entry_ = NULL;
-VM_STUB_CODE_LIST(STUB_CODE_DECLARE);
+StubEntry* StubCode::entries_[kNumStubEntries] = {
+#define STUB_CODE_DECLARE(name) NULL,
+ VM_STUB_CODE_LIST(STUB_CODE_DECLARE)
#undef STUB_CODE_DECLARE
+};
StubEntry::StubEntry(const Code& code)
@@ -42,16 +44,17 @@
#define STUB_CODE_GENERATE(name) \
code ^= Generate("_stub_" #name, StubCode::Generate##name##Stub); \
- name##_entry_ = new StubEntry(code);
+ entries_[k##name##Index] = new StubEntry(code);
void StubCode::InitOnce() {
-#if !defined(DART_PRECOMPILED_RUNTIME)
+#if defined(DART_PRECOMPILED_RUNTIME)
+ // Stubs will be loaded from the snapshot.
+ UNREACHABLE();
+#else
// Generate all the stubs.
Code& code = Code::Handle();
VM_STUB_CODE_LIST(STUB_CODE_GENERATE);
-#else
- UNREACHABLE();
#endif // DART_PRECOMPILED_RUNTIME
}
@@ -59,30 +62,6 @@
#undef STUB_CODE_GENERATE
-void StubCode::Push(Serializer* serializer) {
-#define WRITE_STUB(name) serializer->Push(StubCode::name##_entry()->code());
- VM_STUB_CODE_LIST(WRITE_STUB);
-#undef WRITE_STUB
-}
-
-
-void StubCode::WriteRef(Serializer* serializer) {
-#define WRITE_STUB(name) serializer->WriteRef(StubCode::name##_entry()->code());
- VM_STUB_CODE_LIST(WRITE_STUB);
-#undef WRITE_STUB
-}
-
-
-void StubCode::ReadRef(Deserializer* deserializer) {
- Code& code = Code::Handle();
-#define READ_STUB(name) \
- code ^= deserializer->ReadRef(); \
- name##_entry_ = new StubEntry(code);
- VM_STUB_CODE_LIST(READ_STUB);
-#undef READ_STUB
-}
-
-
void StubCode::Init(Isolate* isolate) {}
diff --git a/runtime/vm/stub_code.h b/runtime/vm/stub_code.h
index 35d589d..cba3cdf 100644
--- a/runtime/vm/stub_code.h
+++ b/runtime/vm/stub_code.h
@@ -17,8 +17,6 @@
class RawCode;
class SnapshotReader;
class SnapshotWriter;
-class Serializer;
-class Deserializer;
// List of stubs created in the VM isolate, these stubs are shared by different
// isolates running in this dart process.
@@ -125,10 +123,6 @@
// only once and the stub code resides in the vm_isolate heap.
static void InitOnce();
- static void Push(Serializer* serializer);
- static void WriteRef(Serializer* serializer);
- static void ReadRef(Deserializer* deserializer);
-
// Generate all stubs which are generated on a per isolate basis as they
// have embedded objects which are isolate specific.
static void Init(Isolate* isolate);
@@ -150,7 +144,7 @@
// Define the shared stub code accessors.
#define STUB_CODE_ACCESSOR(name) \
- static const StubEntry* name##_entry() { return name##_entry_; } \
+ static const StubEntry* name##_entry() { return entries_[k##name##Index]; } \
static intptr_t name##Size() { return name##_entry()->Size(); }
VM_STUB_CODE_LIST(STUB_CODE_ACCESSOR);
#undef STUB_CODE_ACCESSOR
@@ -161,6 +155,12 @@
static const intptr_t kNoInstantiator = 0;
+ static StubEntry* EntryAt(intptr_t index) { return entries_[index]; }
+ static void EntryAtPut(intptr_t index, StubEntry* entry) {
+ entries_[index] = entry;
+ }
+ static intptr_t NumEntries() { return kNumStubEntries; }
+
private:
friend class MegamorphicCacheTable;
@@ -168,12 +168,17 @@
#define STUB_CODE_GENERATE(name) \
static void Generate##name##Stub(Assembler* assembler);
- VM_STUB_CODE_LIST(STUB_CODE_GENERATE);
+ VM_STUB_CODE_LIST(STUB_CODE_GENERATE)
#undef STUB_CODE_GENERATE
-#define STUB_CODE_ENTRY(name) static StubEntry* name##_entry_;
- VM_STUB_CODE_LIST(STUB_CODE_ENTRY);
+ enum {
+#define STUB_CODE_ENTRY(name) k##name##Index,
+ VM_STUB_CODE_LIST(STUB_CODE_ENTRY)
#undef STUB_CODE_ENTRY
+ kNumStubEntries
+ };
+
+ static StubEntry* entries_[kNumStubEntries];
// Generate the stub and finalize the generated code into the stub
// code executable area.
diff --git a/runtime/vm/thread.cc b/runtime/vm/thread.cc
index 6fca06b..1b3428e 100644
--- a/runtime/vm/thread.cc
+++ b/runtime/vm/thread.cc
@@ -91,7 +91,6 @@
deferred_interrupts_(0),
stack_overflow_count_(0),
cha_(NULL),
- type_range_cache_(NULL),
deopt_id_(0),
pending_functions_(GrowableObjectArray::null()),
active_exception_(Object::null()),
diff --git a/runtime/vm/thread.h b/runtime/vm/thread.h
index 65bbdf0..576d57c 100644
--- a/runtime/vm/thread.h
+++ b/runtime/vm/thread.h
@@ -52,7 +52,6 @@
class TimelineStream;
class TypeArguments;
class TypeParameter;
-class TypeRangeCache;
class Zone;
#define REUSABLE_HANDLE_LIST(V) \
@@ -305,11 +304,6 @@
cha_ = value;
}
- TypeRangeCache* type_range_cache() const { return type_range_cache_; }
- void set_type_range_cache(TypeRangeCache* value) {
- type_range_cache_ = value;
- }
-
int32_t no_callback_scope_depth() const { return no_callback_scope_depth_; }
void IncrementNoCallbackScopeDepth() {
@@ -704,7 +698,6 @@
// Compiler state:
CHA* cha_;
- TypeRangeCache* type_range_cache_;
intptr_t deopt_id_; // Compilation specific counter.
RawGrowableObjectArray* pending_functions_;
diff --git a/runtime/vm/version.h b/runtime/vm/version.h
index 2acf205..5f08dd3 100644
--- a/runtime/vm/version.h
+++ b/runtime/vm/version.h
@@ -13,10 +13,12 @@
public:
static const char* String();
static const char* SnapshotString();
+ static const char* CommitString();
private:
static const char* str_;
static const char* snapshot_hash_;
+ static const char* commit_;
};
} // namespace dart
diff --git a/runtime/vm/version_in.cc b/runtime/vm/version_in.cc
index d196310..1857ce9 100644
--- a/runtime/vm/version_in.cc
+++ b/runtime/vm/version_in.cc
@@ -26,7 +26,13 @@
return snapshot_hash_;
}
+
+const char* Version::CommitString() {
+ return commit_;
+}
+
const char* Version::snapshot_hash_ = "{{SNAPSHOT_HASH}}";
const char* Version::str_ = "{{VERSION_STR}} ({{BUILD_TIME}})";
+const char* Version::commit_ = "{{VERSION_STR}}";
} // namespace dart
diff --git a/runtime/vm/vm_sources.gypi b/runtime/vm/vm_sources.gypi
index 990a486..9b1d27c 100644
--- a/runtime/vm/vm_sources.gypi
+++ b/runtime/vm/vm_sources.gypi
@@ -269,6 +269,7 @@
'isolate_test.cc',
'jit_optimizer.cc',
'jit_optimizer.h',
+ 'json_parser.h',
'json_stream.h',
'json_stream.cc',
'json_test.cc',
@@ -364,6 +365,8 @@
'port_test.cc',
'precompiler.cc',
'precompiler.h',
+ 'program_visitor.cc',
+ 'program_visitor.h',
'kernel.h',
'kernel.cc',
'kernel_binary.cc',
diff --git a/sdk/lib/core/errors.dart b/sdk/lib/core/errors.dart
index c1dff42..16f2ffb 100644
--- a/sdk/lib/core/errors.dart
+++ b/sdk/lib/core/errors.dart
@@ -222,7 +222,7 @@
(message != null) ? message : "Value not in range");
/**
- * Create a new [RangeError] with for an invalid value being outside a range.
+ * Create a new [RangeError] for a value being outside the valid range.
*
* The allowed range is from [minValue] to [maxValue], inclusive.
* If `minValue` or `maxValue` are `null`, the range is infinite in
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index 04ed9e6..d16d0d0 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -1209,8 +1209,8 @@
return _create_2(blobParts, bag);
}
- static _create_1(parts) => JS('Blob', 'new Blob(#)', parts);
- static _create_2(parts, bag) => JS('Blob', 'new Blob(#, #)', parts, bag);
+ static _create_1(parts) => JS('Blob', 'new window.Blob(#)', parts);
+ static _create_2(parts, bag) => JS('Blob', 'new window.Blob(#, #)', parts, bag);
static _create_bag() => JS('var', '{}');
static _bag_set(bag, key, value) { JS('void', '#[#] = #', bag, key, value); }
diff --git a/sdk/lib/isolate/isolate.dart b/sdk/lib/isolate/isolate.dart
index f33b63c..1cc9d8e 100644
--- a/sdk/lib/isolate/isolate.dart
+++ b/sdk/lib/isolate/isolate.dart
@@ -439,7 +439,8 @@
* The isolate is requested to terminate itself.
* The [priority] argument specifies when this must happen.
*
- * The [priority] must be one of [IMMEDIATE] or [BEFORE_NEXT_EVENT].
+ * The [priority], when provided, must be one of [IMMEDIATE] or
+ * [BEFORE_NEXT_EVENT] (the default).
* The shutdown is performed at different times depending on the priority:
*
* * `IMMEDIATE`: The isolate shuts down as soon as possible.
diff --git a/tests/co19/co19-co19.status b/tests/co19/co19-co19.status
index 3233640..3c1d647 100644
--- a/tests/co19/co19-co19.status
+++ b/tests/co19/co19-co19.status
@@ -14,6 +14,7 @@
[ $runtime == vm || $runtime != vm ]
# Tests that fail everywhere, including the analyzer.
+Language/Statements/Assert/syntax_t04: Pass, Fail # assert now has an optional second parameter.
LibTest/typed_data/ByteData/buffer_A01_t01: Fail # co19 r736 bug - sent comment.
LibTest/core/RegExp/firstMatch_A01_t01: Fail # co19 issue 742
diff --git a/tests/compiler/dart2js/all_native_test.dart b/tests/compiler/dart2js/all_native_test.dart
new file mode 100644
index 0000000..24cbdb2
--- /dev/null
+++ b/tests/compiler/dart2js/all_native_test.dart
@@ -0,0 +1,25 @@
+// 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 'package:async_helper/async_helper.dart';
+import 'package:compiler/src/common/names.dart';
+import 'package:compiler/src/commandline_options.dart';
+import 'package:expect/expect.dart';
+import 'memory_compiler.dart';
+
+main() {
+ asyncTest(() async {
+ DiagnosticCollector collector = new DiagnosticCollector();
+ await runCompiler(
+ entryPoint: Uris.dart_html,
+ diagnosticHandler: collector,
+ options: [Flags.analyzeAll, Flags.verbose]);
+ int allNativeUsedCount =
+ collector.verboseInfos.where((CollectedMessage message) {
+ return message.text.startsWith('All native types marked as used due to ');
+ }).length;
+ Expect.equals(
+ 1, allNativeUsedCount, "Unexpected message count: $allNativeUsedCount");
+ });
+}
diff --git a/tests/compiler/dart2js/assert_message_throw_test.dart b/tests/compiler/dart2js/assert_message_throw_test.dart
index 75a5bb4..898e3aa 100644
--- a/tests/compiler/dart2js/assert_message_throw_test.dart
+++ b/tests/compiler/dart2js/assert_message_throw_test.dart
@@ -7,6 +7,7 @@
import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/elements/elements.dart';
import 'package:compiler/src/types/masks.dart';
+import 'package:compiler/src/world.dart' show ClosedWorld;
import 'package:expect/expect.dart';
import 'memory_compiler.dart';
import 'type_mask_test_helper.dart';
@@ -58,19 +59,20 @@
memorySourceFiles: {'main.dart': SOURCE},
options: [Flags.enableCheckedMode, Flags.enableAssertMessage]);
Compiler compiler = result.compiler;
+ ClosedWorld closedWorld = compiler.resolverWorld.closedWorldForTesting;
void check(String methodName, TypeMask expectedReturnType) {
Element element = compiler.mainApp.find(methodName);
TypeMask typeMask = simplify(
compiler.globalInference.results.resultOf(element).returnType,
- compiler);
+ closedWorld);
Expect.equals(expectedReturnType, typeMask,
"Unexpected return type on method '$methodName'.");
}
- check('test0', compiler.closedWorld.commonMasks.growableListType);
- check('test1', compiler.closedWorld.commonMasks.nullType);
- check('test2', compiler.closedWorld.commonMasks.uint31Type.nullable());
- check('test3', compiler.closedWorld.commonMasks.intType);
+ check('test0', closedWorld.commonMasks.growableListType);
+ check('test1', closedWorld.commonMasks.nullType);
+ check('test2', closedWorld.commonMasks.uint31Type.nullable());
+ check('test3', closedWorld.commonMasks.intType);
});
}
diff --git a/tests/compiler/dart2js/call_site_simple_type_inferer_test.dart b/tests/compiler/dart2js/call_site_simple_type_inferer_test.dart
index f12fe38..44ea2ba 100644
--- a/tests/compiler/dart2js/call_site_simple_type_inferer_test.dart
+++ b/tests/compiler/dart2js/call_site_simple_type_inferer_test.dart
@@ -2,8 +2,9 @@
// 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:async_helper/async_helper.dart';
+import 'package:compiler/src/types/masks.dart';
import 'package:expect/expect.dart';
-import "package:async_helper/async_helper.dart";
import 'compiler_helper.dart';
import 'type_mask_test_helper.dart';
@@ -206,109 +207,85 @@
}
""";
-void doTest(String test, bool enableInlining, Function f) {
+typedef List<TypeMask> TestCallback(CommonMasks masks);
+
+void doTest(String test, bool enableInlining, TestCallback f) {
compileAndFind(test, 'A', 'x', enableInlining, (compiler, element) {
- var expectedTypes = f(compiler);
+ var inferrer = compiler.globalInference.typesInferrerInternal;
+ var closedWorld = inferrer.closedWorld;
+ var expectedTypes = f(closedWorld.commonMasks);
var signature = element.functionSignature;
int index = 0;
- var inferrer = compiler.globalInference.typesInferrerInternal;
signature.forEachParameter((Element element) {
Expect.equals(expectedTypes[index++],
- simplify(inferrer.getTypeOfElement(element), compiler), test);
+ simplify(inferrer.getTypeOfElement(element), closedWorld), test);
});
Expect.equals(index, expectedTypes.length);
});
}
-void runTest(String test, Function f) {
+void runTest(String test, TestCallback f) {
doTest(test, false, f);
doTest(test, true, f);
}
-subclassOfInterceptor(compiler) {
- return findTypeMask(compiler, 'Interceptor', 'nonNullSubclass');
-}
-
void test() {
- runTest(TEST_1, (compiler) => [compiler.closedWorld.commonMasks.stringType]);
- runTest(TEST_2, (compiler) => [compiler.closedWorld.commonMasks.uint31Type]);
- runTest(TEST_3, (compiler) => [compiler.closedWorld.commonMasks.intType]);
- runTest(TEST_4, (compiler) => [compiler.closedWorld.commonMasks.numType]);
- runTest(TEST_5, (compiler) => [compiler.closedWorld.commonMasks.numType]);
- runTest(TEST_6, (compiler) => [compiler.closedWorld.commonMasks.numType]);
- runTest(TEST_7a, (compiler) => [subclassOfInterceptor(compiler)]);
- runTest(
- TEST_7b,
- (compiler) =>
- [compiler.closedWorld.commonMasks.dynamicType.nonNullable()]);
+ runTest(TEST_1, (commonMasks) => [commonMasks.stringType]);
+ runTest(TEST_2, (commonMasks) => [commonMasks.uint31Type]);
+ runTest(TEST_3, (commonMasks) => [commonMasks.intType]);
+ runTest(TEST_4, (commonMasks) => [commonMasks.numType]);
+ runTest(TEST_5, (commonMasks) => [commonMasks.numType]);
+ runTest(TEST_6, (commonMasks) => [commonMasks.numType]);
+ runTest(TEST_7a, (commonMasks) => [commonMasks.interceptorType]);
+ runTest(TEST_7b, (commonMasks) => [commonMasks.dynamicType.nonNullable()]);
runTest(
TEST_8,
- (compiler) => [
- compiler.closedWorld.commonMasks.uint31Type,
- subclassOfInterceptor(compiler),
- compiler.closedWorld.commonMasks.dynamicType.nonNullable()
+ (commonMasks) => [
+ commonMasks.uint31Type,
+ commonMasks.interceptorType,
+ commonMasks.dynamicType.nonNullable()
]);
- runTest(
- TEST_9,
- (compiler) => [
- compiler.closedWorld.commonMasks.uint31Type,
- compiler.closedWorld.commonMasks.uint31Type
- ]);
- runTest(
- TEST_10,
- (compiler) => [
- compiler.closedWorld.commonMasks.uint31Type,
- compiler.closedWorld.commonMasks.uint31Type
- ]);
+ runTest(TEST_9,
+ (commonMasks) => [commonMasks.uint31Type, commonMasks.uint31Type]);
+ runTest(TEST_10,
+ (commonMasks) => [commonMasks.uint31Type, commonMasks.uint31Type]);
runTest(
TEST_11,
- (compiler) =>
- [subclassOfInterceptor(compiler), subclassOfInterceptor(compiler)]);
+ (commonMasks) =>
+ [commonMasks.interceptorType, commonMasks.interceptorType]);
+
+ runTest(TEST_12,
+ (commonMasks) => [commonMasks.stringType, commonMasks.uint31Type]);
+
+ runTest(TEST_13, (commonMasks) => [commonMasks.numType]);
+
+ runTest(TEST_14,
+ (commonMasks) => [commonMasks.uint31Type, commonMasks.stringType]);
runTest(
- TEST_12,
- (compiler) => [
- compiler.closedWorld.commonMasks.stringType,
- compiler.closedWorld.commonMasks.uint31Type
- ]);
-
- runTest(TEST_13, (compiler) => [compiler.closedWorld.commonMasks.numType]);
-
- runTest(
- TEST_14,
- (compiler) => [
- compiler.closedWorld.commonMasks.uint31Type,
- compiler.closedWorld.commonMasks.stringType
- ]);
-
- runTest(
- TEST_15,
- (compiler) => [
- compiler.closedWorld.commonMasks.stringType,
- compiler.closedWorld.commonMasks.boolType
- ]);
+ TEST_15, (commonMasks) => [commonMasks.stringType, commonMasks.boolType]);
runTest(
TEST_16,
- (compiler) => [
- compiler.closedWorld.commonMasks.uint31Type,
- compiler.closedWorld.commonMasks.uint31Type,
- compiler.closedWorld.commonMasks.stringType
+ (commonMasks) => [
+ commonMasks.uint31Type,
+ commonMasks.uint31Type,
+ commonMasks.stringType
]);
runTest(
TEST_17,
- (compiler) => [
- compiler.closedWorld.commonMasks.uint31Type,
- compiler.closedWorld.commonMasks.boolType,
- compiler.closedWorld.commonMasks.doubleType
+ (commonMasks) => [
+ commonMasks.uint31Type,
+ commonMasks.boolType,
+ commonMasks.doubleType
]);
runTest(
TEST_18,
- (compiler) =>
- [subclassOfInterceptor(compiler), subclassOfInterceptor(compiler)]);
+ (commonMasks) =>
+ [commonMasks.interceptorType, commonMasks.interceptorType]);
}
void main() {
diff --git a/tests/compiler/dart2js/class_set_test.dart b/tests/compiler/dart2js/class_set_test.dart
index 9eea4f1..d5e6624 100644
--- a/tests/compiler/dart2js/class_set_test.dart
+++ b/tests/compiler/dart2js/class_set_test.dart
@@ -50,7 +50,7 @@
}
""",
useMockCompiler: false);
- ClosedWorld world = env.compiler.closedWorld;
+ ClosedWorld world = env.closedWorld;
ClassElement A = env.getElement("A");
ClassElement B = env.getElement("B");
@@ -383,7 +383,7 @@
}
""",
useMockCompiler: false);
- ClosedWorld world = env.compiler.closedWorld;
+ ClosedWorld world = env.closedWorld;
ClassElement A = env.getElement("A");
ClassElement B = env.getElement("B");
diff --git a/tests/compiler/dart2js/closure_tracer_test.dart b/tests/compiler/dart2js/closure_tracer_test.dart
index f76bea1..b585ea4 100644
--- a/tests/compiler/dart2js/closure_tracer_test.dart
+++ b/tests/compiler/dart2js/closure_tracer_test.dart
@@ -154,13 +154,14 @@
Uri uri = new Uri(scheme: 'source');
var compiler = compilerFor(TEST, uri);
asyncTest(() => compiler.run(uri).then((_) {
- var commonMasks = compiler.closedWorld.commonMasks;
var typesInferrer = compiler.globalInference.typesInferrerInternal;
+ var closedWorld = typesInferrer.closedWorld;
+ var commonMasks = closedWorld.commonMasks;
checkType(String name, type) {
var element = findElement(compiler, name);
var mask = typesInferrer.getReturnTypeOfElement(element);
- Expect.equals(type.nullable(), simplify(mask, compiler), name);
+ Expect.equals(type.nullable(), simplify(mask, closedWorld), name);
}
checkType('testFunctionStatement', commonMasks.uint31Type);
diff --git a/tests/compiler/dart2js/compiler_helper.dart b/tests/compiler/dart2js/compiler_helper.dart
index ccf41fa..c21397e 100644
--- a/tests/compiler/dart2js/compiler_helper.dart
+++ b/tests/compiler/dart2js/compiler_helper.dart
@@ -197,35 +197,6 @@
return element;
}
-types.TypeMask findTypeMask(compiler, String name,
- [String how = 'nonNullExact']) {
- var sourceName = name;
- var element = compiler.mainApp.find(sourceName);
- if (element == null) {
- element = compiler.backend.helpers.interceptorsLibrary.find(sourceName);
- }
- if (element == null) {
- element = compiler.commonElements.coreLibrary.find(sourceName);
- }
- Expect.isNotNull(element, 'Could not locate $name');
- switch (how) {
- case 'exact':
- return new types.TypeMask.exact(element, compiler.closedWorld);
- case 'nonNullExact':
- return new types.TypeMask.nonNullExact(element, compiler.closedWorld);
- case 'subclass':
- return new types.TypeMask.subclass(element, compiler.closedWorld);
- case 'nonNullSubclass':
- return new types.TypeMask.nonNullSubclass(element, compiler.closedWorld);
- case 'subtype':
- return new types.TypeMask.subtype(element, compiler.closedWorld);
- case 'nonNullSubtype':
- return new types.TypeMask.nonNullSubtype(element, compiler.closedWorld);
- }
- Expect.fail('Unknown TypeMask constructor $how');
- return null;
-}
-
String anyIdentifier = "[a-zA-Z][a-zA-Z0-9]*";
String getIntTypeCheck(String variable) {
diff --git a/tests/compiler/dart2js/concrete_type_inference_test.dart b/tests/compiler/dart2js/concrete_type_inference_test.dart
index ce5b556..2efb5d7 100644
--- a/tests/compiler/dart2js/concrete_type_inference_test.dart
+++ b/tests/compiler/dart2js/concrete_type_inference_test.dart
@@ -16,49 +16,52 @@
});
}
-void checkPrintType(String expression, checkType(compiler, type)) {
+void checkPrintType(String expression, checkType(closedWorld, type)) {
asyncTest(() => compileAndFind('main() { print($expression); }', 'print',
(compiler, printElement) {
var parameter = printElement.functionSignature.requiredParameters.first;
- checkType(compiler, _typeOf(compiler, parameter));
+ checkType(compiler.resolverWorld.closedWorldForTesting,
+ _typeOf(compiler, parameter));
}));
asyncTest(() =>
compileAndFind('main() { var x = print; print($expression); }', 'print',
(compiler, printElement) {
var parameter = printElement.functionSignature.requiredParameters.first;
- checkType(compiler, _typeOf(compiler, parameter));
+ checkType(compiler.resolverWorld.closedWorldForTesting,
+ _typeOf(compiler, parameter));
}));
asyncTest(() => compileAndFind(
'main() { print($expression); print($expression); }', 'print',
(compiler, printElement) {
var parameter = printElement.functionSignature.requiredParameters.first;
- checkType(compiler, _typeOf(compiler, parameter));
+ checkType(compiler.resolverWorld.closedWorldForTesting,
+ _typeOf(compiler, parameter));
}));
}
void testBasicTypes() {
- checkPrintType('true', (compiler, type) {
+ checkPrintType('true', (closedWorld, type) {
if (type.isForwarding) type = type.forwardTo;
- Expect.identical(compiler.closedWorld.commonMasks.boolType, type);
+ Expect.identical(closedWorld.commonMasks.boolType, type);
});
- checkPrintType('1.5', (compiler, type) {
- Expect.identical(compiler.closedWorld.commonMasks.doubleType, type);
+ checkPrintType('1.5', (closedWorld, type) {
+ Expect.identical(closedWorld.commonMasks.doubleType, type);
});
- checkPrintType('1', (compiler, type) {
- Expect.identical(compiler.closedWorld.commonMasks.uint31Type, type);
+ checkPrintType('1', (closedWorld, type) {
+ Expect.identical(closedWorld.commonMasks.uint31Type, type);
});
- checkPrintType('[]', (compiler, type) {
+ checkPrintType('[]', (closedWorld, type) {
if (type.isForwarding) type = type.forwardTo;
- Expect.identical(compiler.closedWorld.commonMasks.growableListType, type);
+ Expect.identical(closedWorld.commonMasks.growableListType, type);
});
- checkPrintType('null', (compiler, type) {
- Expect.identical(compiler.closedWorld.commonMasks.nullType, type);
+ checkPrintType('null', (closedWorld, type) {
+ Expect.identical(closedWorld.commonMasks.nullType, type);
});
- checkPrintType('"foo"', (compiler, type) {
- Expect.isTrue(compiler.closedWorld.commonMasks.stringType
- .containsOnlyString(compiler.closedWorld));
+ checkPrintType('"foo"', (closedWorld, type) {
+ Expect.isTrue(
+ closedWorld.commonMasks.stringType.containsOnlyString(closedWorld));
});
}
@@ -68,7 +71,7 @@
var firstParameter = fiskElement.functionSignature.requiredParameters[0];
var secondParameter = fiskElement.functionSignature.optionalParameters[0];
var thirdParameter = fiskElement.functionSignature.optionalParameters[1];
- var commonMasks = compiler.closedWorld.commonMasks;
+ var commonMasks = compiler.resolverWorld.closedWorldForTesting.commonMasks;
Expect.identical(commonMasks.uint31Type, _typeOf(compiler, firstParameter));
Expect.identical(commonMasks.nullType, _typeOf(compiler, secondParameter));
Expect.identical(commonMasks.nullType, _typeOf(compiler, thirdParameter));
diff --git a/tests/compiler/dart2js/container_mask_equal_test.dart b/tests/compiler/dart2js/container_mask_equal_test.dart
index 9f67840..5bb5298 100644
--- a/tests/compiler/dart2js/container_mask_equal_test.dart
+++ b/tests/compiler/dart2js/container_mask_equal_test.dart
@@ -31,6 +31,7 @@
var result = await runCompiler(memorySourceFiles: MEMORY_SOURCE_FILES);
var compiler = result.compiler;
var typesInferrer = compiler.globalInference.typesInferrerInternal;
+ var closedWorld = typesInferrer.closedWorld;
var element = compiler.mainApp.find('a');
var mask1 = typesInferrer.getReturnTypeOfElement(element);
@@ -44,7 +45,7 @@
element = compiler.mainApp.find('d');
var mask4 = typesInferrer.getReturnTypeOfElement(element);
- Expect.notEquals(mask1.union(mask2, compiler.closedWorld),
- mask3.union(mask4, compiler.closedWorld));
+ Expect.notEquals(
+ mask1.union(mask2, closedWorld), mask3.union(mask4, closedWorld));
});
}
diff --git a/tests/compiler/dart2js/diagnostic_helper.dart b/tests/compiler/dart2js/diagnostic_helper.dart
index 7d82a3d..6f63e8a 100644
--- a/tests/compiler/dart2js/diagnostic_helper.dart
+++ b/tests/compiler/dart2js/diagnostic_helper.dart
@@ -65,6 +65,10 @@
return filterMessagesByKinds([Diagnostic.CRASH]);
}
+ Iterable<CollectedMessage> get verboseInfos {
+ return filterMessagesByKinds([Diagnostic.VERBOSE_INFO]);
+ }
+
/// `true` if non-verbose messages has been collected.
bool get hasRegularMessages {
return messages.any((m) => m.kind != Diagnostic.VERBOSE_INFO);
diff --git a/tests/compiler/dart2js/dictionary_types_test.dart b/tests/compiler/dart2js/dictionary_types_test.dart
index 15a4e57..ff37cab 100644
--- a/tests/compiler/dart2js/dictionary_types_test.dart
+++ b/tests/compiler/dart2js/dictionary_types_test.dart
@@ -105,19 +105,18 @@
void main() {
asyncTest(() async {
- await compileAndTest("AddAll.dart", (types, getType, compiler) {
+ await compileAndTest("AddAll.dart", (types, getType, closedWorld) {
Expect.equals(getType('int'), types.uint31Type);
Expect.equals(getType('anotherInt'), types.uint31Type);
Expect.equals(getType('dynamic'), types.dynamicType);
Expect.equals(getType('nullOrInt'), types.uint31Type.nullable());
});
- await compileAndTest("Union.dart", (types, getType, compiler) {
+ await compileAndTest("Union.dart", (types, getType, closedWorld) {
Expect.equals(getType('nullOrInt'), types.uint31Type.nullable());
- Expect
- .isTrue(getType('aString').containsOnlyString(compiler.closedWorld));
+ Expect.isTrue(getType('aString').containsOnlyString(closedWorld));
Expect.equals(getType('doubleOrNull'), types.doubleType.nullable());
});
- await compileAndTest("ValueType.dart", (types, getType, compiler) {
+ await compileAndTest("ValueType.dart", (types, getType, closedWorld) {
Expect.equals(getType('knownDouble'), types.doubleType);
Expect.equals(getType('intOrNull'), types.uint31Type.nullable());
Expect.equals(getType('justNull'), types.nullType);
@@ -125,7 +124,7 @@
await compileAndTest("Propagation.dart", (code) {
Expect.isFalse(code.contains("J.\$add\$ns"));
}, createCode: true);
- await compileAndTest("Bailout.dart", (types, getType, compiler) {
+ await compileAndTest("Bailout.dart", (types, getType, closedWorld) {
Expect.equals(getType('notInt'), types.dynamicType);
Expect.equals(getType('alsoNotInt'), types.dynamicType);
Expect.isFalse(getType('dict').isDictionary);
@@ -141,15 +140,16 @@
compiler.stopAfterTypeInference = !createCode;
});
var compiler = result.compiler;
- var commonMasks = compiler.closedWorld.commonMasks;
var typesInferrer = compiler.globalInference.typesInferrerInternal;
+ var closedWorld = typesInferrer.closedWorld;
+ var commonMasks = closedWorld.commonMasks;
getType(String name) {
var element = findElement(compiler, name);
return typesInferrer.getTypeOfElement(element);
}
if (!createCode) {
- checker(commonMasks, getType, compiler);
+ checker(commonMasks, getType, closedWorld);
} else {
var element = compiler.mainFunction;
var code = compiler.backend.getGeneratedCode(element);
diff --git a/tests/compiler/dart2js/dump_info_test.dart b/tests/compiler/dart2js/dump_info_test.dart
index 4f89313..3778de3 100644
--- a/tests/compiler/dart2js/dump_info_test.dart
+++ b/tests/compiler/dart2js/dump_info_test.dart
@@ -104,7 +104,7 @@
var dumpTask = compiler.dumpInfoTask;
StringBuffer sb = new StringBuffer();
- dumpTask.dumpInfoJson(sb, compiler.closedWorld);
+ dumpTask.dumpInfoJson(sb, compiler.resolverWorld.closedWorldForTesting);
String json = sb.toString();
Map<String, dynamic> map = JSON.decode(json);
diff --git a/tests/compiler/dart2js/expect_annotations_test.dart b/tests/compiler/dart2js/expect_annotations_test.dart
index c9c47e0..e8b5e18 100644
--- a/tests/compiler/dart2js/expect_annotations_test.dart
+++ b/tests/compiler/dart2js/expect_annotations_test.dart
@@ -8,6 +8,7 @@
import 'package:compiler/src/elements/elements.dart';
import 'package:compiler/src/js_backend/js_backend.dart';
import 'package:compiler/src/types/types.dart';
+import 'package:compiler/src/world.dart' show ClosedWorld;
import 'type_mask_test_helper.dart';
import 'memory_compiler.dart';
@@ -51,6 +52,7 @@
CompilationResult result =
await runCompiler(memorySourceFiles: MEMORY_SOURCE_FILES);
Compiler compiler = result.compiler;
+ ClosedWorld closedWorld = compiler.resolverWorld.closedWorldForTesting;
Expect.isFalse(compiler.compilationFailed, 'Unsuccessful compilation');
JavaScriptBackend backend = compiler.backend;
Expect.isNotNull(backend.annotations.expectNoInlineClass,
@@ -65,12 +67,12 @@
for (ParameterElement parameter in function.parameters) {
TypeMask type = inferrer.getTypeOfElement(parameter);
Expect.equals(
- expectedParameterType, simplify(type, compiler), "$parameter");
+ expectedParameterType, simplify(type, closedWorld), "$parameter");
}
if (expectedReturnType != null) {
TypeMask type = inferrer.getReturnTypeOfElement(function);
Expect.equals(
- expectedReturnType, simplify(type, compiler), "$function");
+ expectedReturnType, simplify(type, closedWorld), "$function");
}
}
@@ -97,15 +99,15 @@
testTypeMatch(
method, expectedParameterType, expectedReturnType, inferrer);
} else if (expectAssumeDynamic) {
- testTypeMatch(method, compiler.closedWorld.commonMasks.dynamicType,
- null, inferrer);
+ testTypeMatch(
+ method, closedWorld.commonMasks.dynamicType, null, inferrer);
}
}
- TypeMask jsStringType = compiler.closedWorld.commonMasks.stringType;
- TypeMask jsIntType = compiler.closedWorld.commonMasks.intType;
- TypeMask coreStringType = new TypeMask.subtype(
- compiler.coreClasses.stringClass, compiler.closedWorld);
+ TypeMask jsStringType = closedWorld.commonMasks.stringType;
+ TypeMask jsIntType = closedWorld.commonMasks.intType;
+ TypeMask coreStringType =
+ new TypeMask.subtype(compiler.coreClasses.stringClass, closedWorld);
test('method');
test('methodAssumeDynamic', expectAssumeDynamic: true);
diff --git a/tests/compiler/dart2js/field_type_simple_inferer_test.dart b/tests/compiler/dart2js/field_type_simple_inferer_test.dart
index 0e930a0..98defee 100644
--- a/tests/compiler/dart2js/field_type_simple_inferer_test.dart
+++ b/tests/compiler/dart2js/field_type_simple_inferer_test.dart
@@ -5,8 +5,7 @@
import 'package:expect/expect.dart';
import 'package:async_helper/async_helper.dart';
import 'package:compiler/src/types/types.dart' show TypeMask;
-import 'package:compiler/src/types/masks.dart' show CommonMasks;
-import 'package:compiler/src/compiler.dart' show Compiler;
+import 'package:compiler/src/world.dart' show ClosedWorld;
import 'compiler_helper.dart';
import 'type_mask_test_helper.dart';
@@ -471,16 +470,17 @@
}
""";
-typedef TypeMask TestCallback(Compiler compiler, CommonMasks masks);
+typedef TypeMask TestCallback(ClosedWorld closedWorld);
void doTest(
String test, bool disableInlining, Map<String, TestCallback> fields) {
fields.forEach((String name, TestCallback f) {
compileAndFind(test, 'A', name, disableInlining, (compiler, field) {
- TypeMask type = f(compiler, compiler.closedWorld.commonMasks);
var inferrer = compiler.globalInference.typesInferrerInternal;
+ var closedWorld = inferrer.closedWorld;
+ TypeMask type = f(closedWorld);
TypeMask inferredType =
- simplify(inferrer.getTypeOfElement(field), inferrer.compiler);
+ simplify(inferrer.getTypeOfElement(field), closedWorld);
Expect.equals(type, inferredType, test);
});
});
@@ -492,114 +492,122 @@
}
void test() {
- TypeMask subclassOfInterceptor(Compiler compiler, CommonMasks types) =>
- findTypeMask(compiler, 'Interceptor', 'nonNullSubclass');
-
- runTest(
- TEST_1, <String, TestCallback>{'f': (compiler, types) => types.nullType});
+ runTest(TEST_1, <String, TestCallback>{
+ 'f': (closedWorld) => closedWorld.commonMasks.nullType
+ });
runTest(TEST_2, <String, TestCallback>{
- 'f1': (compiler, types) => types.nullType,
- 'f2': (compiler, types) => types.uint31Type
+ 'f1': (closedWorld) => closedWorld.commonMasks.nullType,
+ 'f2': (closedWorld) => closedWorld.commonMasks.uint31Type
});
runTest(TEST_3, <String, TestCallback>{
- 'f1': (compiler, types) => types.uint31Type,
- 'f2': (compiler, types) => types.uint31Type.nullable()
+ 'f1': (closedWorld) => closedWorld.commonMasks.uint31Type,
+ 'f2': (closedWorld) => closedWorld.commonMasks.uint31Type.nullable()
});
runTest(TEST_4, <String, TestCallback>{
- 'f1': subclassOfInterceptor,
- 'f2': (compiler, types) => types.stringType.nullable()
+ 'f1': (closedWorld) => closedWorld.commonMasks.interceptorType,
+ 'f2': (closedWorld) => closedWorld.commonMasks.stringType.nullable()
});
// TODO(ngeoffray): We should try to infer that the initialization
// code at the declaration site of the fields does not matter.
runTest(TEST_5, <String, TestCallback>{
- 'f1': subclassOfInterceptor,
- 'f2': subclassOfInterceptor
+ 'f1': (closedWorld) => closedWorld.commonMasks.interceptorType,
+ 'f2': (closedWorld) => closedWorld.commonMasks.interceptorType,
});
runTest(TEST_6, <String, TestCallback>{
- 'f1': subclassOfInterceptor,
- 'f2': subclassOfInterceptor
+ 'f1': (closedWorld) => closedWorld.commonMasks.interceptorType,
+ 'f2': (closedWorld) => closedWorld.commonMasks.interceptorType,
});
runTest(TEST_7, <String, TestCallback>{
- 'f1': subclassOfInterceptor,
- 'f2': subclassOfInterceptor
+ 'f1': (closedWorld) => closedWorld.commonMasks.interceptorType,
+ 'f2': (closedWorld) => closedWorld.commonMasks.interceptorType,
});
runTest(TEST_8, <String, TestCallback>{
- 'f': (compiler, types) => types.stringType.nullable()
+ 'f': (closedWorld) => closedWorld.commonMasks.stringType.nullable()
});
runTest(TEST_9, <String, TestCallback>{
- 'f': (compiler, types) => types.stringType.nullable()
+ 'f': (closedWorld) => closedWorld.commonMasks.stringType.nullable()
});
- runTest(TEST_10,
- <String, TestCallback>{'f': (compiler, types) => types.uint31Type});
- runTest(TEST_11,
- <String, TestCallback>{'fs': (compiler, types) => types.uint31Type});
+ runTest(TEST_10, <String, TestCallback>{
+ 'f': (closedWorld) => closedWorld.commonMasks.uint31Type
+ });
+ runTest(TEST_11, <String, TestCallback>{
+ 'fs': (closedWorld) => closedWorld.commonMasks.uint31Type
+ });
// TODO(ngeoffray): We should try to infer that the initialization
// code at the declaration site of the fields does not matter.
- runTest(TEST_12, <String, TestCallback>{'fs': subclassOfInterceptor});
+ runTest(TEST_12, <String, TestCallback>{
+ 'fs': (closedWorld) => closedWorld.commonMasks.interceptorType
+ });
- runTest(TEST_13,
- <String, TestCallback>{'fs': (compiler, types) => types.uint31Type});
- runTest(TEST_14,
- <String, TestCallback>{'f': (compiler, types) => types.uint31Type});
+ runTest(TEST_13, <String, TestCallback>{
+ 'fs': (closedWorld) => closedWorld.commonMasks.uint31Type
+ });
+ runTest(TEST_14, <String, TestCallback>{
+ 'f': (closedWorld) => closedWorld.commonMasks.uint31Type
+ });
runTest(TEST_15, <String, TestCallback>{
- 'f': (compiler, types) {
- ClassElement cls = compiler.backend.helpers.jsIndexableClass;
- return new TypeMask.nonNullSubtype(cls, compiler.closedWorld);
+ 'f': (closedWorld) {
+ ClassElement cls = closedWorld.backendClasses.indexableImplementation;
+ return new TypeMask.nonNullSubtype(cls, closedWorld);
}
});
- runTest(TEST_16, <String, TestCallback>{'f': subclassOfInterceptor});
+ runTest(TEST_16, <String, TestCallback>{
+ 'f': (closedWorld) => closedWorld.commonMasks.interceptorType
+ });
runTest(TEST_17, <String, TestCallback>{
- 'f': (compiler, types) => types.uint31Type.nullable()
+ 'f': (closedWorld) => closedWorld.commonMasks.uint31Type.nullable()
});
runTest(TEST_18, <String, TestCallback>{
- 'f1': (compiler, types) => types.uint31Type,
- 'f2': (compiler, types) => types.stringType,
- 'f3': (compiler, types) => types.dynamicType
+ 'f1': (closedWorld) => closedWorld.commonMasks.uint31Type,
+ 'f2': (closedWorld) => closedWorld.commonMasks.stringType,
+ 'f3': (closedWorld) => closedWorld.commonMasks.dynamicType
});
runTest(TEST_19, <String, TestCallback>{
- 'f1': (compiler, types) => types.uint31Type,
- 'f2': (compiler, types) => types.stringType,
- 'f3': (compiler, types) => types.dynamicType
+ 'f1': (closedWorld) => closedWorld.commonMasks.uint31Type,
+ 'f2': (closedWorld) => closedWorld.commonMasks.stringType,
+ 'f3': (closedWorld) => closedWorld.commonMasks.dynamicType
});
runTest(TEST_20, <String, TestCallback>{
- 'f': (compiler, types) => types.uint31Type.nullable()
+ 'f': (closedWorld) => closedWorld.commonMasks.uint31Type.nullable()
});
runTest(TEST_21, <String, TestCallback>{
- 'f': (compiler, types) => types.uint31Type.nullable()
+ 'f': (closedWorld) => closedWorld.commonMasks.uint31Type.nullable()
});
runTest(TEST_22, <String, TestCallback>{
- 'f1': (compiler, types) => types.uint31Type,
- 'f2': (compiler, types) => types.uint31Type,
- 'f3': (compiler, types) => types.stringType.nullable()
+ 'f1': (closedWorld) => closedWorld.commonMasks.uint31Type,
+ 'f2': (closedWorld) => closedWorld.commonMasks.uint31Type,
+ 'f3': (closedWorld) => closedWorld.commonMasks.stringType.nullable()
});
runTest(TEST_23, <String, TestCallback>{
- 'f1': (compiler, types) => types.uint31Type.nullable(),
- 'f2': (compiler, types) => types.uint31Type.nullable(),
- 'f3': (compiler, types) => types.uint31Type.nullable(),
- 'f4': (compiler, types) => types.uint31Type.nullable()
+ 'f1': (closedWorld) => closedWorld.commonMasks.uint31Type.nullable(),
+ 'f2': (closedWorld) => closedWorld.commonMasks.uint31Type.nullable(),
+ 'f3': (closedWorld) => closedWorld.commonMasks.uint31Type.nullable(),
+ 'f4': (closedWorld) => closedWorld.commonMasks.uint31Type.nullable()
});
runTest(TEST_24, <String, TestCallback>{
- 'f1': (compiler, types) => types.positiveIntType,
- 'f2': (compiler, types) => types.positiveIntType,
- 'f3': (compiler, types) => types.uint31Type,
- 'f4': (compiler, types) => types.uint31Type,
- 'f5': (compiler, types) => types.numType.nullable(),
- 'f6': (compiler, types) => types.stringType.nullable()
+ 'f1': (closedWorld) => closedWorld.commonMasks.positiveIntType,
+ 'f2': (closedWorld) => closedWorld.commonMasks.positiveIntType,
+ 'f3': (closedWorld) => closedWorld.commonMasks.uint31Type,
+ 'f4': (closedWorld) => closedWorld.commonMasks.uint31Type,
+ 'f5': (closedWorld) => closedWorld.commonMasks.numType.nullable(),
+ 'f6': (closedWorld) => closedWorld.commonMasks.stringType.nullable()
});
- runTest(TEST_25,
- <String, TestCallback>{'f1': (compiler, types) => types.uint31Type});
- runTest(TEST_26,
- <String, TestCallback>{'f1': (compiler, types) => types.positiveIntType});
+ runTest(TEST_25, <String, TestCallback>{
+ 'f1': (closedWorld) => closedWorld.commonMasks.uint31Type
+ });
+ runTest(TEST_26, <String, TestCallback>{
+ 'f1': (closedWorld) => closedWorld.commonMasks.positiveIntType
+ });
runTest(TEST_27, <String, TestCallback>{
- 'f1': (compiler, types) => types.uint31Type,
- 'f2': (compiler, types) => types.uint31Type.nullable()
+ 'f1': (closedWorld) => closedWorld.commonMasks.uint31Type,
+ 'f2': (closedWorld) => closedWorld.commonMasks.uint31Type.nullable()
});
}
diff --git a/tests/compiler/dart2js/gvn_dynamic_field_get_test.dart b/tests/compiler/dart2js/gvn_dynamic_field_get_test.dart
index eb58e74..d4e866e 100644
--- a/tests/compiler/dart2js/gvn_dynamic_field_get_test.dart
+++ b/tests/compiler/dart2js/gvn_dynamic_field_get_test.dart
@@ -36,7 +36,7 @@
var element = cls.lookupLocalMember(name);
Expect.isNotNull(element);
Selector selector = new Selector.getter(new PublicName(name));
- Expect.isFalse(
- compiler.closedWorld.hasAnyUserDefinedGetter(selector, null));
+ Expect.isFalse(compiler.resolverWorld.closedWorldForTesting
+ .hasAnyUserDefinedGetter(selector, null));
}));
}
diff --git a/tests/compiler/dart2js/issue13354_test.dart b/tests/compiler/dart2js/issue13354_test.dart
index ecf8dba..cf87020 100644
--- a/tests/compiler/dart2js/issue13354_test.dart
+++ b/tests/compiler/dart2js/issue13354_test.dart
@@ -29,14 +29,16 @@
Uri uri = new Uri(scheme: 'source');
var compiler = compilerFor(TEST, uri);
asyncTest(() => compiler.run(uri).then((_) {
- var commonMasks = compiler.closedWorld.commonMasks;
var typesInferrer = compiler.globalInference.typesInferrerInternal;
+ var closedWorld = typesInferrer.closedWorld;
+ var commonMasks = closedWorld.commonMasks;
checkReturn(String name, type) {
var element = findElement(compiler, name);
Expect.equals(
type,
- simplify(typesInferrer.getReturnTypeOfElement(element), compiler),
+ simplify(
+ typesInferrer.getReturnTypeOfElement(element), closedWorld),
name);
}
@@ -46,7 +48,7 @@
Expect.equals(
type,
simplify(
- typesInferrer.getReturnTypeOfElement(element), compiler));
+ typesInferrer.getReturnTypeOfElement(element), closedWorld));
}
checkReturn('bar', commonMasks.uint31Type);
diff --git a/tests/compiler/dart2js/jsinterop/world_test.dart b/tests/compiler/dart2js/jsinterop/world_test.dart
index 074860f..0337799 100644
--- a/tests/compiler/dart2js/jsinterop/world_test.dart
+++ b/tests/compiler/dart2js/jsinterop/world_test.dart
@@ -87,7 +87,7 @@
return cls;
}
- ClosedWorld world = env.compiler.closedWorld;
+ ClosedWorld world = env.closedWorld;
JavaScriptBackend backend = env.compiler.backend;
ClassElement Object_ = registerClass(env.compiler.coreClasses.objectClass);
ClassElement Interceptor =
diff --git a/tests/compiler/dart2js/kernel/closed_world_test.dart b/tests/compiler/dart2js/kernel/closed_world_test.dart
index 8b64123..60a4505 100644
--- a/tests/compiler/dart2js/kernel/closed_world_test.dart
+++ b/tests/compiler/dart2js/kernel/closed_world_test.dart
@@ -136,7 +136,7 @@
}
return true;
}, verbose: arguments.verbose);
- checkClosedWorlds(compiler.closedWorld, closedWorld,
+ checkClosedWorlds(compiler.resolverWorld.closedWorldForTesting, closedWorld,
verbose: arguments.verbose);
});
}
diff --git a/tests/compiler/dart2js/kernel/impact_test.dart b/tests/compiler/dart2js/kernel/impact_test.dart
index fd2467f..90042ef 100644
--- a/tests/compiler/dart2js/kernel/impact_test.dart
+++ b/tests/compiler/dart2js/kernel/impact_test.dart
@@ -168,6 +168,8 @@
testForwardingConstructorTyped();
testForwardingConstructorGeneric();
testEnum();
+ testStaticGenericMethod();
+ testInstanceGenericMethod();
}
testEmpty() {}
@@ -583,6 +585,15 @@
enum Enum { A }
testEnum() => Enum.A;
+
+List<T> staticGenericMethod<T>(T arg) => [arg];
+testStaticGenericMethod() {
+ staticGenericMethod<int>(0);
+}
+
+testInstanceGenericMethod() {
+ new GenericClass<int, String>.generative().genericMethod<bool>(false);
+}
''',
'helper.dart': '''
class Class {
@@ -594,6 +605,8 @@
const GenericClass.generative();
factory GenericClass.fact() => null;
const factory GenericClass.redirect() = GenericClass<X, Y>.generative;
+
+ Map<X, T> genericMethod<T>(T arg) => { null: arg };
}
typedef Typedef();
typedef X GenericTypedef<X, Y>(Y y);
@@ -614,7 +627,9 @@
]);
compiler.resolution.retainCachesForTesting = true;
await compiler.run(entryPoint);
+ checkLibrary(compiler, compiler.mainApp, fullTest: args.contains('--full'));
compiler.libraryLoader.libraries.forEach((LibraryElement library) {
+ if (library == compiler.mainApp) return;
checkLibrary(compiler, library, fullTest: args.contains('--full'));
});
});
diff --git a/tests/compiler/dart2js/kernel/try_catch_test.dart b/tests/compiler/dart2js/kernel/try_catch_test.dart
index 972667c..77a1afd 100644
--- a/tests/compiler/dart2js/kernel/try_catch_test.dart
+++ b/tests/compiler/dart2js/kernel/try_catch_test.dart
@@ -93,4 +93,3 @@
return check(code);
});
}
-
diff --git a/tests/compiler/dart2js/list_tracer2_test.dart b/tests/compiler/dart2js/list_tracer2_test.dart
index c0a5166..215b84a 100644
--- a/tests/compiler/dart2js/list_tracer2_test.dart
+++ b/tests/compiler/dart2js/list_tracer2_test.dart
@@ -25,13 +25,14 @@
var compiler = compilerFor(TEST, uri);
asyncTest(() => compiler.run(uri).then((_) {
var typesInferrer = compiler.globalInference.typesInferrerInternal;
+ var closedWorld = typesInferrer.closedWorld;
checkType(String name, type) {
var element = findElement(compiler, name);
ContainerTypeMask mask = typesInferrer.getTypeOfElement(element);
- Expect.equals(type, simplify(mask.elementType, compiler), name);
+ Expect.equals(type, simplify(mask.elementType, closedWorld), name);
}
- checkType('myList', compiler.closedWorld.commonMasks.uint31Type);
+ checkType('myList', typesInferrer.closedWorld.commonMasks.uint31Type);
}));
}
diff --git a/tests/compiler/dart2js/list_tracer3_test.dart b/tests/compiler/dart2js/list_tracer3_test.dart
index 1e61858..599933c3 100644
--- a/tests/compiler/dart2js/list_tracer3_test.dart
+++ b/tests/compiler/dart2js/list_tracer3_test.dart
@@ -27,16 +27,16 @@
var compiler = compilerFor(TEST, uri);
asyncTest(() => compiler.run(uri).then((_) {
var typesInferrer = compiler.globalInference.typesInferrerInternal;
+ var closedWorld = typesInferrer.closedWorld;
checkType(String name, type) {
var element = findElement(compiler, name);
ContainerTypeMask mask = typesInferrer.getTypeOfElement(element);
- Expect.equals(type, simplify(mask.elementType, compiler), name);
+ Expect.equals(type, simplify(mask.elementType, closedWorld), name);
}
var interceptorType =
- findTypeMask(compiler, 'Interceptor', 'nonNullSubclass');
-
+ typesInferrer.closedWorld.commonMasks.interceptorType;
checkType('myList', interceptorType);
}));
}
diff --git a/tests/compiler/dart2js/list_tracer_test.dart b/tests/compiler/dart2js/list_tracer_test.dart
index c407ce8..e577c9f 100644
--- a/tests/compiler/dart2js/list_tracer_test.dart
+++ b/tests/compiler/dart2js/list_tracer_test.dart
@@ -198,14 +198,15 @@
var compiler = compilerFor(generateTest(allocation), uri,
expectedErrors: 0, expectedWarnings: 1);
asyncTest(() => compiler.run(uri).then((_) {
- var commonMasks = compiler.closedWorld.commonMasks;
var typesInferrer = compiler.globalInference.typesInferrerInternal;
+ var closedWorld = typesInferrer.closedWorld;
+ var commonMasks = closedWorld.commonMasks;
checkType(String name, type) {
var element = findElement(compiler, name);
ContainerTypeMask mask = typesInferrer.getTypeOfElement(element);
if (nullify) type = type.nullable();
- Expect.equals(type, simplify(mask.elementType, compiler), name);
+ Expect.equals(type, simplify(mask.elementType, closedWorld), name);
}
checkType('listInField', commonMasks.numType);
diff --git a/tests/compiler/dart2js/list_tracer_typed_data_length_test.dart b/tests/compiler/dart2js/list_tracer_typed_data_length_test.dart
index ee15963..59ede2b 100644
--- a/tests/compiler/dart2js/list_tracer_typed_data_length_test.dart
+++ b/tests/compiler/dart2js/list_tracer_typed_data_length_test.dart
@@ -6,6 +6,7 @@
import 'package:async_helper/async_helper.dart';
import 'package:compiler/src/types/types.dart' show ContainerTypeMask, TypeMask;
import 'package:compiler/src/compiler.dart';
+import 'package:compiler/src/world.dart' show ClosedWorld;
import 'memory_compiler.dart';
import 'compiler_helper.dart' show findElement;
@@ -30,17 +31,18 @@
CompilationResult result = await runCompiler(memorySourceFiles: TEST);
Compiler compiler = result.compiler;
var typesInferrer = compiler.globalInference.typesInferrerInternal;
+ ClosedWorld closedWorld = typesInferrer.closedWorld;
checkType(String name, type, length) {
var element = findElement(compiler, name);
TypeMask mask = typesInferrer.getTypeOfElement(element);
Expect.isTrue(mask.isContainer);
ContainerTypeMask container = mask;
- Expect.equals(type, simplify(container.elementType, compiler), name);
+ Expect.equals(type, simplify(container.elementType, closedWorld), name);
Expect.equals(container.length, length);
}
- checkType('myList', compiler.closedWorld.commonMasks.numType, 42);
- checkType('myOtherList', compiler.closedWorld.commonMasks.uint31Type, 32);
+ checkType('myList', closedWorld.commonMasks.numType, 42);
+ checkType('myOtherList', closedWorld.commonMasks.uint31Type, 32);
});
}
diff --git a/tests/compiler/dart2js/map_tracer_const_test.dart b/tests/compiler/dart2js/map_tracer_const_test.dart
index 69d9554..69da6a5 100644
--- a/tests/compiler/dart2js/map_tracer_const_test.dart
+++ b/tests/compiler/dart2js/map_tracer_const_test.dart
@@ -33,10 +33,11 @@
var compiler = compilerFor(TEST, uri, expectedErrors: 0, expectedWarnings: 0);
compiler.stopAfterTypeInference = true;
asyncTest(() => compiler.run(uri).then((_) {
- var commonMasks = compiler.closedWorld.commonMasks;
var typesInferrer = compiler.globalInference.typesInferrerInternal;
+ var closedWorld = typesInferrer.closedWorld;
+ var commonMasks = closedWorld.commonMasks;
var element = findElement(compiler, 'closure');
var mask = typesInferrer.getReturnTypeOfElement(element);
- Expect.equals(commonMasks.numType, simplify(mask, compiler));
+ Expect.equals(commonMasks.numType, simplify(mask, closedWorld));
}));
}
diff --git a/tests/compiler/dart2js/map_tracer_keys_test.dart b/tests/compiler/dart2js/map_tracer_keys_test.dart
index 4394879..91c1bf3 100644
--- a/tests/compiler/dart2js/map_tracer_keys_test.dart
+++ b/tests/compiler/dart2js/map_tracer_keys_test.dart
@@ -57,8 +57,8 @@
var compiler = compilerFor(generateTest(key, value, initial), uri,
expectedErrors: 0, expectedWarnings: 0);
asyncTest(() => compiler.run(uri).then((_) {
- var commonMasks = compiler.closedWorld.commonMasks;
var typesInferrer = compiler.globalInference.typesInferrerInternal;
+ var commonMasks = typesInferrer.closedWorld.commonMasks;
var aDoubleType =
typesInferrer.getTypeOfElement(findElement(compiler, 'aDouble'));
var aListType =
diff --git a/tests/compiler/dart2js/map_tracer_test.dart b/tests/compiler/dart2js/map_tracer_test.dart
index 0bd5289..bab5e22 100644
--- a/tests/compiler/dart2js/map_tracer_test.dart
+++ b/tests/compiler/dart2js/map_tracer_test.dart
@@ -212,11 +212,11 @@
var compiler = compilerFor(generateTest(allocation), uri,
expectedErrors: 0, expectedWarnings: 1);
compiler.closeResolution();
- var closedWorld = compiler.closedWorld;
asyncTest(() => compiler.run(uri).then((_) {
var keyType, valueType;
- var commonMasks = compiler.closedWorld.commonMasks;
var typesInferrer = compiler.globalInference.typesInferrerInternal;
+ var closedWorld = typesInferrer.closedWorld;
+ var commonMasks = closedWorld.commonMasks;
var emptyType = new TypeMask.nonNullEmpty();
var aKeyType =
typesInferrer.getTypeOfElement(findElement(compiler, 'aKey'));
@@ -234,14 +234,15 @@
checkType(String name, keyType, valueType) {
var element = findElement(compiler, name);
MapTypeMask mask = typesInferrer.getTypeOfElement(element);
- Expect.equals(keyType, simplify(mask.keyType, compiler), name);
- Expect.equals(valueType, simplify(mask.valueType, compiler), name);
+ Expect.equals(keyType, simplify(mask.keyType, closedWorld), name);
+ Expect.equals(valueType, simplify(mask.valueType, closedWorld), name);
}
K(TypeMask other) =>
- simplify(keyType.union(other, closedWorld), compiler);
+ simplify(keyType.union(other, closedWorld), closedWorld);
V(TypeMask other) =>
- simplify(valueType.union(other, closedWorld), compiler).nullable();
+ simplify(valueType.union(other, closedWorld), closedWorld)
+ .nullable();
checkType('mapInField', K(aKeyType), V(commonMasks.numType));
checkType('mapPassedToMethod', K(aKeyType), V(commonMasks.numType));
diff --git a/tests/compiler/dart2js/mirror_final_field_inferrer2_test.dart b/tests/compiler/dart2js/mirror_final_field_inferrer2_test.dart
index 3d5ce6d..4563009 100644
--- a/tests/compiler/dart2js/mirror_final_field_inferrer2_test.dart
+++ b/tests/compiler/dart2js/mirror_final_field_inferrer2_test.dart
@@ -28,9 +28,12 @@
var result = await runCompiler(memorySourceFiles: MEMORY_SOURCE_FILES);
var compiler = result.compiler;
var element = findElement(compiler, 'field');
- var commonMasks = compiler.closedWorld.commonMasks;
var typesInferrer = compiler.globalInference.typesInferrerInternal;
- Expect.equals(commonMasks.uint31Type,
- simplify(typesInferrer.getTypeOfElement(element), compiler), 'field');
+ var closedWorld = typesInferrer.closedWorld;
+ var commonMasks = closedWorld.commonMasks;
+ Expect.equals(
+ commonMasks.uint31Type,
+ simplify(typesInferrer.getTypeOfElement(element), closedWorld),
+ 'field');
});
}
diff --git a/tests/compiler/dart2js/mirror_final_field_inferrer_test.dart b/tests/compiler/dart2js/mirror_final_field_inferrer_test.dart
index 78ea487..0934e37 100644
--- a/tests/compiler/dart2js/mirror_final_field_inferrer_test.dart
+++ b/tests/compiler/dart2js/mirror_final_field_inferrer_test.dart
@@ -28,9 +28,12 @@
var result = await runCompiler(memorySourceFiles: MEMORY_SOURCE_FILES);
var compiler = result.compiler;
var element = findElement(compiler, 'field');
- var commonMasks = compiler.closedWorld.commonMasks;
var typesInferrer = compiler.globalInference.typesInferrerInternal;
- Expect.equals(commonMasks.uint31Type,
- simplify(typesInferrer.getTypeOfElement(element), compiler), 'field');
+ var closedWorld = typesInferrer.closedWorld;
+ var commonMasks = closedWorld.commonMasks;
+ Expect.equals(
+ commonMasks.uint31Type,
+ simplify(typesInferrer.getTypeOfElement(element), closedWorld),
+ 'field');
});
}
diff --git a/tests/compiler/dart2js/needs_no_such_method_test.dart b/tests/compiler/dart2js/needs_no_such_method_test.dart
index 892087e..6cd1ae6 100644
--- a/tests/compiler/dart2js/needs_no_such_method_test.dart
+++ b/tests/compiler/dart2js/needs_no_such_method_test.dart
@@ -52,7 +52,7 @@
bar = new Selector.call(const PublicName('bar'), CallStructure.NO_ARGS);
baz = new Selector.call(const PublicName('baz'), CallStructure.NO_ARGS);
- closedWorld = env.compiler.closedWorld;
+ closedWorld = env.closedWorld;
superclass = env.getElement('Superclass');
subclass = env.getElement('Subclass');
subtype = env.getElement('Subtype');
diff --git a/tests/compiler/dart2js/patch_test.dart b/tests/compiler/dart2js/patch_test.dart
index 4277cd4..523f825 100644
--- a/tests/compiler/dart2js/patch_test.dart
+++ b/tests/compiler/dart2js/patch_test.dart
@@ -974,7 +974,7 @@
runCompiler: true,
analyzeOnly: true);
compiler.closeResolution();
- ClosedWorld world = compiler.closedWorld;
+ ClosedWorld world = compiler.resolverWorld.closedWorldForTesting;
ClassElement cls = ensure(
compiler, "A", compiler.commonElements.coreLibrary.find,
diff --git a/tests/compiler/dart2js/related_types.dart b/tests/compiler/dart2js/related_types.dart
index af65613..61203ec 100644
--- a/tests/compiler/dart2js/related_types.dart
+++ b/tests/compiler/dart2js/related_types.dart
@@ -36,7 +36,6 @@
/// Check all loaded libraries in [compiler] for unrelated types.
void checkRelatedTypes(Compiler compiler) {
compiler.closeResolution();
- compiler.closedWorld;
for (LibraryElement library in compiler.libraryLoader.libraries) {
checkLibraryElement(compiler, library);
}
@@ -78,7 +77,7 @@
: this.resolvedAst = resolvedAst,
super(resolvedAst.elements);
- ClosedWorld get world => compiler.closedWorld;
+ ClosedWorld get world => compiler.resolverWorld.closedWorldForTesting;
CoreClasses get coreClasses => compiler.coreClasses;
diff --git a/tests/compiler/dart2js/serialization/model_test_helper.dart b/tests/compiler/dart2js/serialization/model_test_helper.dart
index e970d22..735205d 100644
--- a/tests/compiler/dart2js/serialization/model_test_helper.dart
+++ b/tests/compiler/dart2js/serialization/model_test_helper.dart
@@ -98,8 +98,8 @@
checkResolutionEnqueuers(compilerNormal.enqueuer.resolution,
compilerDeserialized.enqueuer.resolution,
verbose: verbose);
- checkClosedWorlds(
- compilerNormal.closedWorld, compilerDeserialized.closedWorld,
+ checkClosedWorlds(compilerNormal.resolverWorld.closedWorldForTesting,
+ compilerDeserialized.resolverWorld.closedWorldForTesting,
verbose: verbose);
checkBackendInfo(compilerNormal, compilerDeserialized, verbose: verbose);
});
diff --git a/tests/compiler/dart2js/simple_inferrer_and_or_test.dart b/tests/compiler/dart2js/simple_inferrer_and_or_test.dart
index 2c81edc..edb66ec 100644
--- a/tests/compiler/dart2js/simple_inferrer_and_or_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_and_or_test.dart
@@ -97,32 +97,31 @@
var compiler = compilerFor(TEST, uri);
asyncTest(() => compiler.run(uri).then((_) {
var typesInferrer = compiler.globalInference.typesInferrerInternal;
+ var closedWorld = typesInferrer.closedWorld;
checkReturn(String name, type) {
var element = findElement(compiler, name);
Expect.equals(
type,
simplify(
- typesInferrer.getReturnTypeOfElement(element), compiler));
+ typesInferrer.getReturnTypeOfElement(element), closedWorld));
}
- var subclassOfInterceptor =
- findTypeMask(compiler, 'Interceptor', 'nonNullSubclass');
+ var subclassOfInterceptor = closedWorld.commonMasks.interceptorType;
checkReturn('returnDyn1', subclassOfInterceptor);
checkReturn('returnDyn2', subclassOfInterceptor);
checkReturn('returnDyn3', subclassOfInterceptor);
- checkReturn('returnDyn4',
- compiler.closedWorld.commonMasks.dynamicType.nonNullable());
- checkReturn('returnDyn5',
- compiler.closedWorld.commonMasks.dynamicType.nonNullable());
- checkReturn('returnDyn6',
- compiler.closedWorld.commonMasks.dynamicType.nonNullable());
+ checkReturn(
+ 'returnDyn4', closedWorld.commonMasks.dynamicType.nonNullable());
+ checkReturn(
+ 'returnDyn5', closedWorld.commonMasks.dynamicType.nonNullable());
+ checkReturn(
+ 'returnDyn6', closedWorld.commonMasks.dynamicType.nonNullable());
checkReturn('returnDyn7', subclassOfInterceptor);
checkReturn('returnDyn7b', subclassOfInterceptor);
checkReturn('returnDyn8', subclassOfInterceptor);
checkReturn('returnDyn9', subclassOfInterceptor);
- checkReturn(
- 'returnString', compiler.closedWorld.commonMasks.stringType);
+ checkReturn('returnString', closedWorld.commonMasks.stringType);
}));
}
diff --git a/tests/compiler/dart2js/simple_inferrer_callers_test.dart b/tests/compiler/dart2js/simple_inferrer_callers_test.dart
index a6ca00e..dc2b4f9 100644
--- a/tests/compiler/dart2js/simple_inferrer_callers_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_callers_test.dart
@@ -8,7 +8,7 @@
import 'package:async_helper/async_helper.dart';
import 'package:expect/expect.dart';
import 'package:compiler/src/inferrer/type_graph_inferrer.dart';
-import 'package:compiler/src/world.dart' show ClosedWorldRefiner;
+import 'package:compiler/src/world.dart' show ClosedWorld, ClosedWorldRefiner;
import 'compiler_helper.dart';
@@ -40,11 +40,12 @@
var compiler = compilerFor(TEST, uri, analyzeOnly: true);
asyncTest(() => compiler.run(uri).then((_) {
ClosedWorldRefiner closedWorldRefiner = compiler.closeResolution();
+ ClosedWorld closedWorld = compiler.resolverWorld.closedWorldForTesting;
var inferrer =
- new MyInferrer(compiler, compiler.closedWorld, closedWorldRefiner);
+ new MyInferrer(compiler, closedWorld, closedWorldRefiner);
compiler.globalInference.typesInferrerInternal = inferrer;
compiler.globalInference.runGlobalTypeInference(
- compiler.mainFunction, compiler.closedWorld, closedWorldRefiner);
+ compiler.mainFunction, closedWorld, closedWorldRefiner);
var mainElement = findElement(compiler, 'main');
var classA = findElement(compiler, 'A');
var fieldA = classA.lookupLocalMember('field');
diff --git a/tests/compiler/dart2js/simple_inferrer_closure_test.dart b/tests/compiler/dart2js/simple_inferrer_closure_test.dart
index 109f197..39e5811 100644
--- a/tests/compiler/dart2js/simple_inferrer_closure_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_closure_test.dart
@@ -119,29 +119,31 @@
var compiler = compilerFor(TEST, uri);
asyncTest(() => compiler.run(uri).then((_) {
var typesInferrer = compiler.globalInference.typesInferrerInternal;
+ var closedWorld = typesInferrer.closedWorld;
checkReturn(String name, type) {
var element = findElement(compiler, name);
Expect.equals(
type,
- simplify(typesInferrer.getReturnTypeOfElement(element), compiler),
+ simplify(
+ typesInferrer.getReturnTypeOfElement(element), closedWorld),
name);
}
- checkReturn('returnInt1', compiler.closedWorld.commonMasks.uint31Type);
- checkReturn('returnInt2', compiler.closedWorld.commonMasks.uint31Type);
- checkReturn('returnInt3', compiler.closedWorld.commonMasks.uint31Type);
- checkReturn('returnInt4', compiler.closedWorld.commonMasks.uint31Type);
- checkReturn('returnIntOrNull',
- compiler.closedWorld.commonMasks.uint31Type.nullable());
+ checkReturn('returnInt1', closedWorld.commonMasks.uint31Type);
+ checkReturn('returnInt2', closedWorld.commonMasks.uint31Type);
+ checkReturn('returnInt3', closedWorld.commonMasks.uint31Type);
+ checkReturn('returnInt4', closedWorld.commonMasks.uint31Type);
+ checkReturn(
+ 'returnIntOrNull', closedWorld.commonMasks.uint31Type.nullable());
- checkReturn('returnDyn1',
- compiler.closedWorld.commonMasks.dynamicType.nonNullable());
- checkReturn('returnDyn2',
- compiler.closedWorld.commonMasks.dynamicType.nonNullable());
- checkReturn('returnDyn3',
- compiler.closedWorld.commonMasks.dynamicType.nonNullable());
- checkReturn('returnNum1', compiler.closedWorld.commonMasks.numType);
+ checkReturn(
+ 'returnDyn1', closedWorld.commonMasks.dynamicType.nonNullable());
+ checkReturn(
+ 'returnDyn2', closedWorld.commonMasks.dynamicType.nonNullable());
+ checkReturn(
+ 'returnDyn3', closedWorld.commonMasks.dynamicType.nonNullable());
+ checkReturn('returnNum1', closedWorld.commonMasks.numType);
checkReturnInClass(String className, String methodName, type) {
var cls = findElement(compiler, className);
@@ -149,11 +151,11 @@
Expect.equals(
type,
simplify(
- typesInferrer.getReturnTypeOfElement(element), compiler));
+ typesInferrer.getReturnTypeOfElement(element), closedWorld));
}
var cls = findElement(compiler, 'A');
checkReturnInClass(
- 'A', 'foo', new TypeMask.nonNullExact(cls, compiler.closedWorld));
+ 'A', 'foo', new TypeMask.nonNullExact(cls, closedWorld));
}));
}
diff --git a/tests/compiler/dart2js/simple_inferrer_const_closure2_test.dart b/tests/compiler/dart2js/simple_inferrer_const_closure2_test.dart
index 2e59a21..c4c9194 100644
--- a/tests/compiler/dart2js/simple_inferrer_const_closure2_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_const_closure2_test.dart
@@ -29,6 +29,7 @@
var compiler = compilerFor(TEST, uri);
asyncTest(() => compiler.run(uri).then((_) {
var typesInferrer = compiler.globalInference.typesInferrerInternal;
+ var closedWorld = typesInferrer.closedWorld;
checkReturn(String name, type) {
var element = findElement(compiler, name);
@@ -38,7 +39,7 @@
name);
}
- checkReturn('method', compiler.closedWorld.commonMasks.numType);
- checkReturn('returnNum', compiler.closedWorld.commonMasks.numType);
+ checkReturn('method', closedWorld.commonMasks.numType);
+ checkReturn('returnNum', closedWorld.commonMasks.numType);
}));
}
diff --git a/tests/compiler/dart2js/simple_inferrer_const_closure3_test.dart b/tests/compiler/dart2js/simple_inferrer_const_closure3_test.dart
index a354985..af85fa9 100644
--- a/tests/compiler/dart2js/simple_inferrer_const_closure3_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_const_closure3_test.dart
@@ -29,6 +29,7 @@
var compiler = compilerFor(TEST, uri);
asyncTest(() => compiler.run(uri).then((_) {
var typesInferrer = compiler.globalInference.typesInferrerInternal;
+ var closedWorld = typesInferrer.closedWorld;
checkArgument(String functionName, type) {
var functionElement = findElement(compiler, functionName);
@@ -36,10 +37,10 @@
var element = signature.requiredParameters.first;
Expect.equals(
type,
- simplify(typesInferrer.getTypeOfElement(element), compiler),
+ simplify(typesInferrer.getTypeOfElement(element), closedWorld),
functionName);
}
- checkArgument('method', compiler.closedWorld.commonMasks.uint31Type);
+ checkArgument('method', closedWorld.commonMasks.uint31Type);
}));
}
diff --git a/tests/compiler/dart2js/simple_inferrer_const_closure4_test.dart b/tests/compiler/dart2js/simple_inferrer_const_closure4_test.dart
index eeeeb02..2a2fd62 100644
--- a/tests/compiler/dart2js/simple_inferrer_const_closure4_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_const_closure4_test.dart
@@ -30,6 +30,7 @@
var compiler = compilerFor(TEST, uri);
asyncTest(() => compiler.run(uri).then((_) {
var typesInferrer = compiler.globalInference.typesInferrerInternal;
+ var closedWorld = typesInferrer.closedWorld;
checkArgument(String functionName, type) {
var functionElement = findElement(compiler, functionName);
@@ -37,11 +38,11 @@
var element = signature.requiredParameters.first;
Expect.equals(
type,
- simplify(typesInferrer.getTypeOfElement(element), compiler),
+ simplify(typesInferrer.getTypeOfElement(element), closedWorld),
functionName);
}
- checkArgument('method', compiler.closedWorld.commonMasks.numType);
- checkArgument('returnNum', compiler.closedWorld.commonMasks.numType);
+ checkArgument('method', closedWorld.commonMasks.numType);
+ checkArgument('returnNum', closedWorld.commonMasks.numType);
}));
}
diff --git a/tests/compiler/dart2js/simple_inferrer_const_closure5_test.dart b/tests/compiler/dart2js/simple_inferrer_const_closure5_test.dart
index a41c254..41b5feb 100644
--- a/tests/compiler/dart2js/simple_inferrer_const_closure5_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_const_closure5_test.dart
@@ -30,6 +30,7 @@
var compiler = compilerFor(TEST, uri);
asyncTest(() => compiler.run(uri).then((_) {
var typesInferrer = compiler.globalInference.typesInferrerInternal;
+ var closedWorld = typesInferrer.closedWorld;
checkArgument(String functionName, type) {
var functionElement = findElement(compiler, functionName);
@@ -37,10 +38,10 @@
var element = signature.requiredParameters.first;
Expect.equals(
type,
- simplify(typesInferrer.getTypeOfElement(element), compiler),
+ simplify(typesInferrer.getTypeOfElement(element), closedWorld),
functionName);
}
- checkArgument('method', compiler.closedWorld.commonMasks.numType);
+ checkArgument('method', typesInferrer.closedWorld.commonMasks.numType);
}));
}
diff --git a/tests/compiler/dart2js/simple_inferrer_const_closure_default_test.dart b/tests/compiler/dart2js/simple_inferrer_const_closure_default_test.dart
index f2d38c6..ce1cc2c 100644
--- a/tests/compiler/dart2js/simple_inferrer_const_closure_default_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_const_closure_default_test.dart
@@ -43,6 +43,7 @@
var compiler = compilerFor(TEST, uri);
asyncTest(() => compiler.run(uri).then((_) {
var typesInferrer = compiler.globalInference.typesInferrerInternal;
+ var closedWorld = typesInferrer.closedWorld;
checkArgument(String functionName, type) {
var functionElement = findElement(compiler, functionName);
@@ -52,7 +53,7 @@
: signature.optionalParameters.first;
Expect.equals(
type,
- simplify(typesInferrer.getTypeOfElement(element), compiler),
+ simplify(typesInferrer.getTypeOfElement(element), closedWorld),
functionName);
}
@@ -62,51 +63,45 @@
var element = signature.optionalParameters.first;
Expect.equals(
type,
- simplify(typesInferrer.getTypeOfElement(element), compiler),
+ simplify(typesInferrer.getTypeOfElement(element), closedWorld),
functionName);
}
- checkArgument('foo1', compiler.closedWorld.commonMasks.functionType);
+ checkArgument('foo1', closedWorld.commonMasks.functionType);
/// 01: ok
- checkArgument('foo2', compiler.closedWorld.commonMasks.functionType);
+ checkArgument('foo2', closedWorld.commonMasks.functionType);
/// 02: ok
- checkArgument('foo3', compiler.closedWorld.commonMasks.functionType);
+ checkArgument('foo3', closedWorld.commonMasks.functionType);
/// 03: ok
- checkArgument('foo4', compiler.closedWorld.commonMasks.functionType);
+ checkArgument('foo4', closedWorld.commonMasks.functionType);
/// 04: ok
- checkArgument('foo5', compiler.closedWorld.commonMasks.dynamicType);
+ checkArgument('foo5', closedWorld.commonMasks.dynamicType);
/// 05: ok
- checkArgument('foo6', compiler.closedWorld.commonMasks.dynamicType);
+ checkArgument('foo6', closedWorld.commonMasks.dynamicType);
/// 06: ok
- checkArgument(
- 'defaultFn1', compiler.closedWorld.commonMasks.uint31Type);
+ checkArgument('defaultFn1', closedWorld.commonMasks.uint31Type);
/// 07: ok
- checkArgument(
- 'defaultFn2', compiler.closedWorld.commonMasks.uint31Type);
+ checkArgument('defaultFn2', closedWorld.commonMasks.uint31Type);
/// 08: ok
- checkArgument(
- 'defaultFn3', compiler.closedWorld.commonMasks.uint31Type);
+ checkArgument('defaultFn3', closedWorld.commonMasks.uint31Type);
/// 09: ok
- checkArgument(
- 'defaultFn4', compiler.closedWorld.commonMasks.uint31Type);
+ checkArgument('defaultFn4', closedWorld.commonMasks.uint31Type);
/// 10: ok
- checkArgument(
- 'defaultFn5', compiler.closedWorld.commonMasks.uint31Type);
+ checkArgument('defaultFn5', closedWorld.commonMasks.uint31Type);
/// 11: ok
- checkArgument(
- 'defaultFn6', compiler.closedWorld.commonMasks.uint31Type);
+ checkArgument('defaultFn6', closedWorld.commonMasks.uint31Type);
/// 12: ok
}));
diff --git a/tests/compiler/dart2js/simple_inferrer_const_closure_test.dart b/tests/compiler/dart2js/simple_inferrer_const_closure_test.dart
index 6dbd781..6183de0 100644
--- a/tests/compiler/dart2js/simple_inferrer_const_closure_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_const_closure_test.dart
@@ -38,6 +38,7 @@
var compiler = compilerFor(TEST, uri);
asyncTest(() => compiler.run(uri).then((_) {
var typesInferrer = compiler.globalInference.typesInferrerInternal;
+ var closedWorld = typesInferrer.closedWorld;
checkReturn(String name, type) {
var element = findElement(compiler, name);
@@ -47,10 +48,10 @@
name);
}
- checkReturn('method1', compiler.closedWorld.commonMasks.uint31Type);
- checkReturn('returnInt1', compiler.closedWorld.commonMasks.uint31Type);
+ checkReturn('method1', closedWorld.commonMasks.uint31Type);
+ checkReturn('returnInt1', closedWorld.commonMasks.uint31Type);
- checkReturn('method2', compiler.closedWorld.commonMasks.uint31Type);
- checkReturn('returnInt2', compiler.closedWorld.commonMasks.uint31Type);
+ checkReturn('method2', closedWorld.commonMasks.uint31Type);
+ checkReturn('returnInt2', closedWorld.commonMasks.uint31Type);
}));
}
diff --git a/tests/compiler/dart2js/simple_inferrer_final_field3_test.dart b/tests/compiler/dart2js/simple_inferrer_final_field3_test.dart
index 7eeefae..c321c54 100644
--- a/tests/compiler/dart2js/simple_inferrer_final_field3_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_final_field3_test.dart
@@ -28,15 +28,16 @@
var compiler = compilerFor(TEST, uri);
asyncTest(() => compiler.run(uri).then((_) {
var typesInferrer = compiler.globalInference.typesInferrerInternal;
+ var closedWorld = typesInferrer.closedWorld;
checkFieldTypeInClass(String className, String fieldName, type) {
var cls = findElement(compiler, className);
var element = cls.lookupLocalMember(fieldName);
Expect.equals(type,
- simplify(typesInferrer.getTypeOfElement(element), compiler));
+ simplify(typesInferrer.getTypeOfElement(element), closedWorld));
}
- checkFieldTypeInClass('A', 'dynamicField',
- findTypeMask(compiler, 'Interceptor', 'nonNullSubclass'));
+ checkFieldTypeInClass(
+ 'A', 'dynamicField', closedWorld.commonMasks.interceptorType);
}));
}
diff --git a/tests/compiler/dart2js/simple_inferrer_final_field_test.dart b/tests/compiler/dart2js/simple_inferrer_final_field_test.dart
index 78b3ebc..7b14057 100644
--- a/tests/compiler/dart2js/simple_inferrer_final_field_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_final_field_test.dart
@@ -32,21 +32,22 @@
var compiler = compilerFor(TEST, uri);
asyncTest(() => compiler.run(uri).then((_) {
var typesInferrer = compiler.globalInference.typesInferrerInternal;
+ var closedWorld = typesInferrer.closedWorld;
checkFieldTypeInClass(String className, String fieldName, type) {
var cls = findElement(compiler, className);
var element = cls.lookupLocalMember(fieldName);
Expect.equals(type,
- simplify(typesInferrer.getTypeOfElement(element), compiler));
+ simplify(typesInferrer.getTypeOfElement(element), closedWorld));
}
checkFieldTypeInClass(
- 'A', 'intField', compiler.closedWorld.commonMasks.uint31Type);
- checkFieldTypeInClass('A', 'giveUpField1',
- findTypeMask(compiler, 'Interceptor', 'nonNullSubclass'));
- checkFieldTypeInClass('A', 'giveUpField2',
- compiler.closedWorld.commonMasks.dynamicType.nonNullable());
+ 'A', 'intField', closedWorld.commonMasks.uint31Type);
checkFieldTypeInClass(
- 'A', 'fieldParameter', compiler.closedWorld.commonMasks.uint31Type);
+ 'A', 'giveUpField1', closedWorld.commonMasks.interceptorType);
+ checkFieldTypeInClass('A', 'giveUpField2',
+ closedWorld.commonMasks.dynamicType.nonNullable());
+ checkFieldTypeInClass(
+ 'A', 'fieldParameter', closedWorld.commonMasks.uint31Type);
}));
}
diff --git a/tests/compiler/dart2js/simple_inferrer_global_field_closure2_test.dart b/tests/compiler/dart2js/simple_inferrer_global_field_closure2_test.dart
index 01a896a..35969e1 100644
--- a/tests/compiler/dart2js/simple_inferrer_global_field_closure2_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_global_field_closure2_test.dart
@@ -29,6 +29,7 @@
var compiler = compilerFor(TEST, uri);
asyncTest(() => compiler.run(uri).then((_) {
var typesInferrer = compiler.globalInference.typesInferrerInternal;
+ var closedWorld = typesInferrer.closedWorld;
checkArgument(String functionName, type) {
var functionElement = findElement(compiler, functionName);
@@ -36,10 +37,10 @@
var element = signature.requiredParameters.first;
Expect.equals(
type,
- simplify(typesInferrer.getTypeOfElement(element), compiler),
+ simplify(typesInferrer.getTypeOfElement(element), closedWorld),
functionName);
}
- checkArgument('method', compiler.closedWorld.commonMasks.uint31Type);
+ checkArgument('method', closedWorld.commonMasks.uint31Type);
}));
}
diff --git a/tests/compiler/dart2js/simple_inferrer_global_field_closure_test.dart b/tests/compiler/dart2js/simple_inferrer_global_field_closure_test.dart
index f20912a..430f464 100644
--- a/tests/compiler/dart2js/simple_inferrer_global_field_closure_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_global_field_closure_test.dart
@@ -38,6 +38,7 @@
var compiler = compilerFor(TEST, uri);
asyncTest(() => compiler.run(uri).then((_) {
var typesInferrer = compiler.globalInference.typesInferrerInternal;
+ var closedWorld = typesInferrer.closedWorld;
checkReturn(String name, type) {
var element = findElement(compiler, name);
@@ -47,10 +48,10 @@
name);
}
- checkReturn('method1', compiler.closedWorld.commonMasks.uint31Type);
- checkReturn('returnInt1', compiler.closedWorld.commonMasks.uint31Type);
+ checkReturn('method1', closedWorld.commonMasks.uint31Type);
+ checkReturn('returnInt1', closedWorld.commonMasks.uint31Type);
- checkReturn('method2', compiler.closedWorld.commonMasks.uint31Type);
- checkReturn('returnInt2', compiler.closedWorld.commonMasks.uint31Type);
+ checkReturn('method2', closedWorld.commonMasks.uint31Type);
+ checkReturn('returnInt2', closedWorld.commonMasks.uint31Type);
}));
}
diff --git a/tests/compiler/dart2js/simple_inferrer_no_such_method_test.dart b/tests/compiler/dart2js/simple_inferrer_no_such_method_test.dart
index a68120c..dcddd20 100644
--- a/tests/compiler/dart2js/simple_inferrer_no_such_method_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_no_such_method_test.dart
@@ -160,88 +160,82 @@
}
""";
-main() {
+checkReturn(MockCompiler compiler, String name, type) {
+ var typesInferrer = compiler.globalInference.typesInferrerInternal;
+ var element = findElement(compiler, name);
+ Expect.equals(
+ type,
+ simplify(typesInferrer.getReturnTypeOfElement(element),
+ typesInferrer.closedWorld),
+ name);
+}
+
+test1() async {
Uri uri = new Uri(scheme: 'source');
+ var compiler = compilerFor(TEST1, uri);
+ await compiler.run(uri);
+ var closedWorld = compiler.resolverWorld.closedWorldForTesting;
+ checkReturn(compiler, 'test1', closedWorld.commonMasks.uint31Type);
+ checkReturn(
+ compiler, 'test2', closedWorld.commonMasks.dynamicType.nonNullable());
+ checkReturn(compiler, 'test3', closedWorld.commonMasks.uint31Type);
+ checkReturn(compiler, 'test4', closedWorld.commonMasks.mapType);
+ checkReturn(
+ compiler, 'test5', closedWorld.commonMasks.dynamicType.nonNullable());
+ checkReturn(
+ compiler, 'test6', closedWorld.commonMasks.dynamicType.nonNullable());
+}
- checkReturn(MockCompiler compiler, String name, type) {
- var typesInferrer = compiler.globalInference.typesInferrerInternal;
- var element = findElement(compiler, name);
- Expect.equals(
- type,
- simplify(typesInferrer.getReturnTypeOfElement(element), compiler),
- name);
- }
+test2() async {
+ Uri uri = new Uri(scheme: 'source');
+ var compiler = compilerFor(TEST2, uri);
+ await compiler.run(uri);
+ var closedWorld = compiler.resolverWorld.closedWorldForTesting;
+ checkReturn(compiler, 'test1', closedWorld.commonMasks.mapType.nonNullable());
+ checkReturn(compiler, 'test2', closedWorld.commonMasks.mapType);
+ checkReturn(compiler, 'test3', closedWorld.commonMasks.mapType);
+ checkReturn(compiler, 'test4', closedWorld.commonMasks.mapType);
+ checkReturn(compiler, 'test5', closedWorld.commonMasks.mapType);
- var compiler1 = compilerFor(TEST1, uri);
- asyncTest(() => compiler1.run(uri).then((_) {
- checkReturn(
- compiler1, 'test1', compiler1.closedWorld.commonMasks.uint31Type);
- checkReturn(compiler1, 'test2',
- compiler1.closedWorld.commonMasks.dynamicType.nonNullable());
- checkReturn(
- compiler1, 'test3', compiler1.closedWorld.commonMasks.uint31Type);
- checkReturn(
- compiler1, 'test4', compiler1.closedWorld.commonMasks.mapType);
- checkReturn(compiler1, 'test5',
- compiler1.closedWorld.commonMasks.dynamicType.nonNullable());
- checkReturn(compiler1, 'test6',
- compiler1.closedWorld.commonMasks.dynamicType.nonNullable());
- }));
+ checkReturn(compiler, 'test6', closedWorld.commonMasks.numType);
+ checkReturn(compiler, 'test7', closedWorld.commonMasks.uint31Type);
+ checkReturn(compiler, 'test8', closedWorld.commonMasks.uint31Type);
+ checkReturn(compiler, 'test9', closedWorld.commonMasks.uint31Type);
+ checkReturn(compiler, 'test10', closedWorld.commonMasks.numType);
+ checkReturn(compiler, 'test11', closedWorld.commonMasks.doubleType);
+}
- var compiler2 = compilerFor(TEST2, uri);
- asyncTest(() => compiler2.run(uri).then((_) {
- checkReturn(compiler2, 'test1',
- compiler2.closedWorld.commonMasks.mapType.nonNullable());
- checkReturn(
- compiler2, 'test2', compiler2.closedWorld.commonMasks.mapType);
- checkReturn(
- compiler2, 'test3', compiler2.closedWorld.commonMasks.mapType);
- checkReturn(
- compiler2, 'test4', compiler2.closedWorld.commonMasks.mapType);
- checkReturn(
- compiler2, 'test5', compiler2.closedWorld.commonMasks.mapType);
+test3() async {
+ Uri uri = new Uri(scheme: 'source');
+ var compiler = compilerFor(TEST3, uri);
+ await compiler.run(uri);
+ var closedWorld = compiler.resolverWorld.closedWorldForTesting;
+ checkReturn(compiler, 'test1', const TypeMask.nonNullEmpty());
+ checkReturn(compiler, 'test2', closedWorld.commonMasks.mapType);
+ checkReturn(compiler, 'test3', closedWorld.commonMasks.mapType);
+ checkReturn(compiler, 'test4', closedWorld.commonMasks.mapType);
+ checkReturn(compiler, 'test5', closedWorld.commonMasks.mapType);
+ checkReturn(compiler, 'test6', closedWorld.commonMasks.mapType);
+}
- checkReturn(
- compiler2, 'test6', compiler2.closedWorld.commonMasks.numType);
- checkReturn(
- compiler2, 'test7', compiler2.closedWorld.commonMasks.uint31Type);
- checkReturn(
- compiler2, 'test8', compiler2.closedWorld.commonMasks.uint31Type);
- checkReturn(
- compiler2, 'test9', compiler2.closedWorld.commonMasks.uint31Type);
- checkReturn(
- compiler2, 'test10', compiler2.closedWorld.commonMasks.numType);
- checkReturn(
- compiler2, 'test11', compiler2.closedWorld.commonMasks.doubleType);
- }));
+test4() async {
+ Uri uri = new Uri(scheme: 'source');
+ var compiler = compilerFor(TEST4, uri);
+ await compiler.run(uri);
+ var closedWorld = compiler.resolverWorld.closedWorldForTesting;
+ checkReturn(compiler, 'test1', const TypeMask.nonNullEmpty());
+ checkReturn(compiler, 'test2', closedWorld.commonMasks.mapType);
+ checkReturn(compiler, 'test3', closedWorld.commonMasks.mapType);
+ checkReturn(compiler, 'test4', closedWorld.commonMasks.mapType);
+ checkReturn(compiler, 'test5', closedWorld.commonMasks.mapType);
+ checkReturn(compiler, 'test6', closedWorld.commonMasks.mapType);
+}
- var compiler3 = compilerFor(TEST3, uri);
- asyncTest(() => compiler3.run(uri).then((_) {
- checkReturn(compiler3, 'test1', const TypeMask.nonNullEmpty());
- checkReturn(
- compiler3, 'test2', compiler3.closedWorld.commonMasks.mapType);
- checkReturn(
- compiler3, 'test3', compiler3.closedWorld.commonMasks.mapType);
- checkReturn(
- compiler3, 'test4', compiler3.closedWorld.commonMasks.mapType);
- checkReturn(
- compiler3, 'test5', compiler3.closedWorld.commonMasks.mapType);
- checkReturn(
- compiler3, 'test6', compiler3.closedWorld.commonMasks.mapType);
- }));
-
- var compiler4 = compilerFor(TEST4, uri);
- asyncTest(() => compiler4.run(uri).then((_) {
- checkReturn(compiler4, 'test1', const TypeMask.nonNullEmpty());
- checkReturn(
- compiler4, 'test2', compiler4.closedWorld.commonMasks.mapType);
- checkReturn(
- compiler4, 'test3', compiler4.closedWorld.commonMasks.mapType);
- checkReturn(
- compiler4, 'test4', compiler4.closedWorld.commonMasks.mapType);
- checkReturn(
- compiler4, 'test5', compiler4.closedWorld.commonMasks.mapType);
- checkReturn(
- compiler4, 'test6', compiler4.closedWorld.commonMasks.mapType);
- }));
+main() {
+ asyncTest(() async {
+ await test1();
+ await test2();
+ await test3();
+ await test4();
+ });
}
diff --git a/tests/compiler/dart2js/simple_inferrer_postfix_prefix_test.dart b/tests/compiler/dart2js/simple_inferrer_postfix_prefix_test.dart
index 3d37e58..27ed1a4 100644
--- a/tests/compiler/dart2js/simple_inferrer_postfix_prefix_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_postfix_prefix_test.dart
@@ -66,20 +66,21 @@
Uri uri = new Uri(scheme: 'source');
var compiler = compilerFor(TEST, uri);
asyncTest(() => compiler.run(uri).then((_) {
- var commonMasks = compiler.closedWorld.commonMasks;
var typesInferrer = compiler.globalInference.typesInferrerInternal;
+ var closedWorld = typesInferrer.closedWorld;
+ var commonMasks = closedWorld.commonMasks;
checkReturnInClass(String className, String methodName, type) {
var cls = findElement(compiler, className);
var element = cls.lookupLocalMember(methodName);
Expect.equals(
type,
- simplify(typesInferrer.getReturnTypeOfElement(element), compiler),
+ simplify(
+ typesInferrer.getReturnTypeOfElement(element), closedWorld),
methodName);
}
- var subclassOfInterceptor =
- findTypeMask(compiler, 'Interceptor', 'nonNullSubclass');
+ var subclassOfInterceptor = commonMasks.interceptorType;
checkReturnInClass('A', 'returnNum1', commonMasks.numType);
checkReturnInClass('A', 'returnNum2', commonMasks.numType);
diff --git a/tests/compiler/dart2js/simple_inferrer_test.dart b/tests/compiler/dart2js/simple_inferrer_test.dart
index cf29a1a..08b5620 100644
--- a/tests/compiler/dart2js/simple_inferrer_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_test.dart
@@ -727,20 +727,20 @@
var compiler = compilerFor(TEST, uri);
compiler.diagnosticHandler = createHandler(compiler, TEST);
asyncTest(() => compiler.run(uri).then((_) {
- var commonMasks = compiler.closedWorld.commonMasks;
var typesInferrer = compiler.globalInference.typesInferrerInternal;
- var world = compiler.closedWorld;
+ var closedWorld = typesInferrer.closedWorld;
+ var commonMasks = closedWorld.commonMasks;
checkReturn(String name, type) {
var element = findElement(compiler, name);
Expect.equals(
type,
- simplify(typesInferrer.getReturnTypeOfElement(element), compiler),
+ simplify(
+ typesInferrer.getReturnTypeOfElement(element), closedWorld),
name);
}
- var interceptorType =
- findTypeMask(compiler, 'Interceptor', 'nonNullSubclass');
+ var interceptorType = commonMasks.interceptorType;
checkReturn('returnNum1', commonMasks.numType);
checkReturn('returnNum2', commonMasks.numType);
@@ -761,7 +761,7 @@
checkReturn('returnEmpty1', const TypeMask.nonNullEmpty());
checkReturn('returnEmpty2', const TypeMask.nonNullEmpty());
TypeMask intType = new TypeMask.nonNullSubtype(
- compiler.coreClasses.intClass, compiler.closedWorld);
+ compiler.coreClasses.intClass, closedWorld);
checkReturn('testIsCheck1', intType);
checkReturn('testIsCheck2', intType);
checkReturn('testIsCheck3', intType.nullable());
@@ -796,7 +796,7 @@
checkReturn(
'returnAsString',
new TypeMask.subtype(
- compiler.coreClasses.stringClass, compiler.closedWorld));
+ compiler.coreClasses.stringClass, closedWorld));
checkReturn('returnIntAsNum', commonMasks.uint31Type);
checkReturn('returnAsTypedef', commonMasks.functionType.nullable());
checkReturn('returnTopLevelGetter', commonMasks.uint31Type);
@@ -806,9 +806,9 @@
'testSwitch1',
simplify(
commonMasks.intType
- .union(commonMasks.doubleType, compiler.closedWorld)
+ .union(commonMasks.doubleType, closedWorld)
.nullable(),
- compiler));
+ closedWorld));
checkReturn('testSwitch2', commonMasks.uint31Type);
checkReturn('testSwitch3', interceptorType.nullable());
checkReturn('testSwitch4', commonMasks.uint31Type);
@@ -832,7 +832,8 @@
var element = cls.lookupLocalMember(methodName);
Expect.equals(
type,
- simplify(typesInferrer.getReturnTypeOfElement(element), compiler),
+ simplify(
+ typesInferrer.getReturnTypeOfElement(element), closedWorld),
'$className:$methodName');
}
@@ -864,7 +865,7 @@
checkFactoryConstructor(String className, String factoryName) {
var cls = findElement(compiler, className);
var element = cls.localLookup(factoryName);
- Expect.equals(new TypeMask.nonNullExact(cls, world),
+ Expect.equals(new TypeMask.nonNullExact(cls, closedWorld),
typesInferrer.getReturnTypeOfElement(element));
}
@@ -874,7 +875,7 @@
checkReturn(
'testCascade2',
new TypeMask.nonNullExact(
- findElement(compiler, 'CascadeHelper'), world));
+ findElement(compiler, 'CascadeHelper'), closedWorld));
checkReturn('testSpecialization1', commonMasks.numType);
checkReturn('testSpecialization2', commonMasks.dynamicType);
checkReturn('testSpecialization3', commonMasks.uint31Type.nullable());
diff --git a/tests/compiler/dart2js/simple_inferrer_try_catch_test.dart b/tests/compiler/dart2js/simple_inferrer_try_catch_test.dart
index 207a861..b6fc660 100644
--- a/tests/compiler/dart2js/simple_inferrer_try_catch_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_try_catch_test.dart
@@ -167,15 +167,16 @@
Uri uri = new Uri(scheme: 'source');
var compiler = compilerFor(TEST, uri);
asyncTest(() => compiler.run(uri).then((_) {
- var commonMasks = compiler.closedWorld.commonMasks;
var typesInferrer = compiler.globalInference.typesInferrerInternal;
+ var closedWorld = typesInferrer.closedWorld;
+ var commonMasks = closedWorld.commonMasks;
checkReturn(String name, type) {
var element = findElement(compiler, name);
Expect.equals(
type,
simplify(
- typesInferrer.getReturnTypeOfElement(element), compiler));
+ typesInferrer.getReturnTypeOfElement(element), closedWorld));
}
checkReturn('returnInt1', commonMasks.uint31Type);
@@ -186,10 +187,9 @@
checkReturn(
'returnInt6',
new TypeMask.nonNullSubtype(
- compiler.coreClasses.intClass, compiler.closedWorld));
+ closedWorld.coreClasses.intClass, closedWorld));
- var subclassOfInterceptor =
- findTypeMask(compiler, 'Interceptor', 'nonNullSubclass');
+ var subclassOfInterceptor = commonMasks.interceptorType;
checkReturn('returnDyn1', subclassOfInterceptor);
checkReturn('returnDyn2', subclassOfInterceptor);
diff --git a/tests/compiler/dart2js/simple_inferrer_unregister_call_test.dart b/tests/compiler/dart2js/simple_inferrer_unregister_call_test.dart
index f0be6f8..8456a95 100644
--- a/tests/compiler/dart2js/simple_inferrer_unregister_call_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_unregister_call_test.dart
@@ -41,6 +41,6 @@
}
checkReturnInClass(
- 'A', '+', compiler.closedWorld.commonMasks.uint31Type);
+ 'A', '+', typesInferrer.closedWorld.commonMasks.uint31Type);
}));
}
diff --git a/tests/compiler/dart2js/subtypeset_test.dart b/tests/compiler/dart2js/subtypeset_test.dart
index 1f0fd7f..418e547 100644
--- a/tests/compiler/dart2js/subtypeset_test.dart
+++ b/tests/compiler/dart2js/subtypeset_test.dart
@@ -47,7 +47,7 @@
""",
useMockCompiler: false)
.then((env) {
- ClosedWorld world = env.compiler.closedWorld;
+ ClosedWorld world = env.closedWorld;
ClassElement A = env.getElement("A");
ClassElement B = env.getElement("B");
diff --git a/tests/compiler/dart2js/trust_type_annotations_test.dart b/tests/compiler/dart2js/trust_type_annotations_test.dart
index 764e5ef..70fb5f1 100644
--- a/tests/compiler/dart2js/trust_type_annotations_test.dart
+++ b/tests/compiler/dart2js/trust_type_annotations_test.dart
@@ -51,6 +51,7 @@
var compiler = compilerFor(TEST, uri, trustTypeAnnotations: true);
asyncTest(() => compiler.run(uri).then((_) {
var typesInferrer = compiler.globalInference.typesInferrerInternal;
+ var closedWorld = typesInferrer.closedWorld;
ClassElement classA = findElement(compiler, "A");
@@ -58,18 +59,17 @@
var element = classA.lookupMember(name);
var mask = typesInferrer.getReturnTypeOfElement(element);
Expect.isTrue(type.containsMask(
- typesInferrer.getReturnTypeOfElement(element),
- compiler.closedWorld));
+ typesInferrer.getReturnTypeOfElement(element), closedWorld));
}
checkType(String name, type) {
var element = classA.lookupMember(name);
Expect.isTrue(type.containsMask(
- typesInferrer.getTypeOfElement(element), compiler.closedWorld));
+ typesInferrer.getTypeOfElement(element), closedWorld));
}
- var intMask = new TypeMask.subtype(
- compiler.coreClasses.intClass, compiler.closedWorld);
+ var intMask =
+ new TypeMask.subtype(compiler.coreClasses.intClass, closedWorld);
checkReturn('foo', intMask);
checkReturn('faa', intMask);
diff --git a/tests/compiler/dart2js/type_combination_test.dart b/tests/compiler/dart2js/type_combination_test.dart
index fc68975..479e717 100644
--- a/tests/compiler/dart2js/type_combination_test.dart
+++ b/tests/compiler/dart2js/type_combination_test.dart
@@ -102,8 +102,9 @@
}
void testUnion(MockCompiler compiler) {
- RuleSet ruleSet = new RuleSet('union',
- (t1, t2) => simplify(t1.union(t2, compiler.closedWorld), compiler));
+ ClosedWorld closedWorld = compiler.resolverWorld.closedWorldForTesting;
+ RuleSet ruleSet = new RuleSet(
+ 'union', (t1, t2) => simplify(t1.union(t2, closedWorld), closedWorld));
rule(type1, type2, result) => ruleSet.rule(type1, type2, result);
check(type1, type2, predicate) => ruleSet.check(type1, type2, predicate);
@@ -415,8 +416,9 @@
void testIntersection(MockCompiler compiler) {
JavaScriptBackend backend = compiler.backend;
BackendHelpers helpers = backend.helpers;
- RuleSet ruleSet = new RuleSet(
- 'intersection', (t1, t2) => t1.intersection(t2, compiler.closedWorld));
+ ClosedWorld closedWorld = compiler.resolverWorld.closedWorldForTesting;
+ RuleSet ruleSet =
+ new RuleSet('intersection', (t1, t2) => t1.intersection(t2, closedWorld));
rule(type1, type2, result) => ruleSet.rule(type1, type2, result);
rule(emptyType, emptyType, emptyType);
@@ -557,9 +559,9 @@
rule(jsIndexable, nonPrimitive1, emptyType);
rule(jsIndexable, nonPrimitive2, emptyType);
rule(jsIndexable, potentialArray,
- new TypeMask.nonNullSubtype(helpers.jsArrayClass, compiler.closedWorld));
+ new TypeMask.nonNullSubtype(helpers.jsArrayClass, closedWorld));
rule(jsIndexable, potentialString,
- new TypeMask.nonNullSubtype(helpers.jsStringClass, compiler.closedWorld));
+ new TypeMask.nonNullSubtype(helpers.jsStringClass, closedWorld));
rule(jsIndexable, jsBooleanOrNull, emptyType);
rule(jsIndexable, jsNumberOrNull, emptyType);
rule(jsIndexable, jsIntegerOrNull, emptyType);
@@ -724,10 +726,11 @@
}
void testRegressions(MockCompiler compiler) {
+ ClosedWorld closedWorld = compiler.resolverWorld.closedWorldForTesting;
TypeMask nonNullPotentialString =
- new TypeMask.nonNullSubtype(patternClass, compiler.closedWorld);
+ new TypeMask.nonNullSubtype(patternClass, closedWorld);
Expect.equals(potentialString,
- jsStringOrNull.union(nonNullPotentialString, compiler.closedWorld));
+ jsStringOrNull.union(nonNullPotentialString, closedWorld));
}
void main() {
@@ -757,57 +760,62 @@
.registerTypeUse(new TypeUse.instantiation(patternImplClass.rawType));
compiler.enqueuer.resolution.applyImpact(impactBuilder);
compiler.closeResolution();
- ClosedWorld world = compiler.closedWorld;
+ ClosedWorld closedWorld = compiler.resolverWorld.closedWorldForTesting;
// Grab hold of a supertype for String so we can produce potential
// string types.
- patternClass = compiler.commonElements.coreLibrary.find('Pattern');
+ patternClass = closedWorld.commonElements.coreLibrary.find('Pattern');
- nonPrimitive1 =
- new TypeMask.nonNullSubtype(compiler.coreClasses.mapClass, world);
- nonPrimitive2 =
- new TypeMask.nonNullSubtype(compiler.coreClasses.functionClass, world);
+ nonPrimitive1 = new TypeMask.nonNullSubtype(
+ closedWorld.coreClasses.mapClass, closedWorld);
+ nonPrimitive2 = new TypeMask.nonNullSubtype(
+ closedWorld.coreClasses.functionClass, closedWorld);
potentialArray =
- new TypeMask.subtype(compiler.coreClasses.listClass, world);
- potentialString = new TypeMask.subtype(patternClass, world);
+ new TypeMask.subtype(closedWorld.coreClasses.listClass, closedWorld);
+ potentialString = new TypeMask.subtype(patternClass, closedWorld);
jsInterceptor =
- new TypeMask.nonNullSubclass(helpers.jsInterceptorClass, world);
- jsArrayOrNull = new TypeMask.subclass(helpers.jsArrayClass, world);
- jsReadableArray = new TypeMask.nonNullSubclass(helpers.jsArrayClass, world);
+ new TypeMask.nonNullSubclass(helpers.jsInterceptorClass, closedWorld);
+ jsArrayOrNull = new TypeMask.subclass(helpers.jsArrayClass, closedWorld);
+ jsReadableArray =
+ new TypeMask.nonNullSubclass(helpers.jsArrayClass, closedWorld);
jsMutableArrayOrNull =
- new TypeMask.subclass(helpers.jsMutableArrayClass, world);
+ new TypeMask.subclass(helpers.jsMutableArrayClass, closedWorld);
jsMutableArray =
- new TypeMask.nonNullSubclass(helpers.jsMutableArrayClass, world);
- jsFixedArrayOrNull = new TypeMask.exact(helpers.jsFixedArrayClass, world);
- jsFixedArray = new TypeMask.nonNullExact(helpers.jsFixedArrayClass, world);
+ new TypeMask.nonNullSubclass(helpers.jsMutableArrayClass, closedWorld);
+ jsFixedArrayOrNull =
+ new TypeMask.exact(helpers.jsFixedArrayClass, closedWorld);
+ jsFixedArray =
+ new TypeMask.nonNullExact(helpers.jsFixedArrayClass, closedWorld);
jsExtendableArrayOrNull =
- new TypeMask.exact(helpers.jsExtendableArrayClass, world);
+ new TypeMask.exact(helpers.jsExtendableArrayClass, closedWorld);
jsExtendableArray =
- new TypeMask.nonNullExact(helpers.jsExtendableArrayClass, world);
+ new TypeMask.nonNullExact(helpers.jsExtendableArrayClass, closedWorld);
jsUnmodifiableArrayOrNull =
- new TypeMask.exact(helpers.jsUnmodifiableArrayClass, world);
- jsUnmodifiableArray =
- new TypeMask.nonNullExact(helpers.jsUnmodifiableArrayClass, world);
- jsIndexableOrNull = new TypeMask.subtype(helpers.jsIndexableClass, world);
- jsIndexable = new TypeMask.nonNullSubtype(helpers.jsIndexableClass, world);
+ new TypeMask.exact(helpers.jsUnmodifiableArrayClass, closedWorld);
+ jsUnmodifiableArray = new TypeMask.nonNullExact(
+ helpers.jsUnmodifiableArrayClass, closedWorld);
+ jsIndexableOrNull =
+ new TypeMask.subtype(helpers.jsIndexableClass, closedWorld);
+ jsIndexable =
+ new TypeMask.nonNullSubtype(helpers.jsIndexableClass, closedWorld);
jsInterceptorOrNull =
- new TypeMask.subclass(helpers.jsInterceptorClass, world);
- jsStringOrNull = new TypeMask.exact(helpers.jsStringClass, world);
- jsString = new TypeMask.nonNullExact(helpers.jsStringClass, world);
- jsBoolean = new TypeMask.nonNullExact(helpers.jsBoolClass, world);
- jsNumber = new TypeMask.nonNullSubclass(helpers.jsNumberClass, world);
- jsInteger = new TypeMask.nonNullExact(helpers.jsIntClass, world);
- jsDouble = new TypeMask.nonNullExact(helpers.jsDoubleClass, world);
- jsBooleanOrNull = new TypeMask.exact(helpers.jsBoolClass, world);
- jsNumberOrNull = new TypeMask.subclass(helpers.jsNumberClass, world);
- jsIntegerOrNull = new TypeMask.exact(helpers.jsIntClass, world);
- jsDoubleOrNull = new TypeMask.exact(helpers.jsDoubleClass, world);
+ new TypeMask.subclass(helpers.jsInterceptorClass, closedWorld);
+ jsStringOrNull = new TypeMask.exact(helpers.jsStringClass, closedWorld);
+ jsString = new TypeMask.nonNullExact(helpers.jsStringClass, closedWorld);
+ jsBoolean = new TypeMask.nonNullExact(helpers.jsBoolClass, closedWorld);
+ jsNumber = new TypeMask.nonNullSubclass(helpers.jsNumberClass, closedWorld);
+ jsInteger = new TypeMask.nonNullExact(helpers.jsIntClass, closedWorld);
+ jsDouble = new TypeMask.nonNullExact(helpers.jsDoubleClass, closedWorld);
+ jsBooleanOrNull = new TypeMask.exact(helpers.jsBoolClass, closedWorld);
+ jsNumberOrNull = new TypeMask.subclass(helpers.jsNumberClass, closedWorld);
+ jsIntegerOrNull = new TypeMask.exact(helpers.jsIntClass, closedWorld);
+ jsDoubleOrNull = new TypeMask.exact(helpers.jsDoubleClass, closedWorld);
nullType = const TypeMask.empty();
- objectType =
- new TypeMask.nonNullSubclass(compiler.coreClasses.objectClass, world);
+ objectType = new TypeMask.nonNullSubclass(
+ closedWorld.coreClasses.objectClass, closedWorld);
emptyType = const TypeMask.nonNullEmpty();
dynamicType =
- new TypeMask.subclass(compiler.coreClasses.objectClass, world);
+ new TypeMask.subclass(closedWorld.coreClasses.objectClass, closedWorld);
Expect.notEquals(
emptyType, nonPrimitive1, "nonPrimitive1 expected to be non-empty.");
diff --git a/tests/compiler/dart2js/type_inference6_test.dart b/tests/compiler/dart2js/type_inference6_test.dart
index a9cdc0a..ce18f9b 100644
--- a/tests/compiler/dart2js/type_inference6_test.dart
+++ b/tests/compiler/dart2js/type_inference6_test.dart
@@ -24,11 +24,12 @@
Uri uri = new Uri(scheme: 'source');
var compiler = compilerFor(TEST, uri);
return compiler.run(uri).then((_) {
- var commonMasks = compiler.closedWorld.commonMasks;
var typesInferrer = compiler.globalInference.typesInferrerInternal;
+ var closedWorld = typesInferrer.closedWorld;
+ var commonMasks = closedWorld.commonMasks;
var element = findElement(compiler, "foo");
var mask = typesInferrer.getReturnTypeOfElement(element);
- Expect.equals(commonMasks.uint31Type, simplify(mask, compiler));
+ Expect.equals(commonMasks.uint31Type, simplify(mask, closedWorld));
});
}
diff --git a/tests/compiler/dart2js/type_inference7_test.dart b/tests/compiler/dart2js/type_inference7_test.dart
index a8ebbb0..e4ec10f 100644
--- a/tests/compiler/dart2js/type_inference7_test.dart
+++ b/tests/compiler/dart2js/type_inference7_test.dart
@@ -23,13 +23,15 @@
// Assertions enabled:
var compiler = compilerFor(TEST, uri, enableUserAssertions: true);
await compiler.run(uri);
- var commonMasks = compiler.closedWorld.commonMasks;
var typesInferrer = compiler.globalInference.typesInferrerInternal;
+ var closedWorld = typesInferrer.closedWorld;
+ var commonMasks = closedWorld.commonMasks;
var foo = findElement(compiler, "foo");
// Return type is null|bool.
var mask = typesInferrer.getReturnTypeOfElement(foo);
Expect.isTrue(mask.isNullable);
- Expect.equals(commonMasks.boolType, simplify(mask.nonNullable(), compiler));
+ Expect.equals(
+ commonMasks.boolType, simplify(mask.nonNullable(), closedWorld));
// First parameter is uint31|String|bool.
var mask1 = typesInferrer.getTypeOfElement(foo.parameters[0]);
Expect.isTrue(mask1.isUnion);
@@ -37,7 +39,7 @@
[commonMasks.uint31Type, commonMasks.stringType, commonMasks.boolType]);
for (var typeMask in mask1.disjointMasks) {
Expect.isFalse(typeMask.isNullable);
- var simpleType = simplify(typeMask, compiler);
+ var simpleType = simplify(typeMask, closedWorld);
Expect.isTrue(expectedTypes.remove(simpleType), "$simpleType");
}
Expect.isTrue(expectedTypes.isEmpty);
@@ -45,15 +47,16 @@
var mask2 = typesInferrer.getTypeOfElement(foo.parameters[1]);
Expect.isTrue(mask2.isNullable);
Expect.equals(
- commonMasks.boolType, simplify(mask2.nonNullable(), compiler));
+ commonMasks.boolType, simplify(mask2.nonNullable(), closedWorld));
}
{
// Assertions disabled:
var compiler = compilerFor(TEST, uri, enableUserAssertions: false);
await compiler.run(uri);
- var commonMasks = compiler.closedWorld.commonMasks;
var typesInferrer = compiler.globalInference.typesInferrerInternal;
+ var closedWorld = typesInferrer.closedWorld;
+ var commonMasks = closedWorld.commonMasks;
var foo = findElement(compiler, "foo");
// Return type is null.
var mask = typesInferrer.getReturnTypeOfElement(foo);
@@ -62,11 +65,11 @@
// First parameter is uint31.
var mask1 = typesInferrer.getTypeOfElement(foo.parameters[0]);
Expect.isFalse(mask1.isNullable);
- Expect.equals(commonMasks.uint31Type, simplify(mask1, compiler));
+ Expect.equals(commonMasks.uint31Type, simplify(mask1, closedWorld));
// Second parameter is null.
var mask2 = typesInferrer.getTypeOfElement(foo.parameters[1]);
Expect.isTrue(mask2.isNullable);
- Expect.isTrue(simplify(mask2.nonNullable(), compiler).isEmpty);
+ Expect.isTrue(simplify(mask2.nonNullable(), closedWorld).isEmpty);
}
}
diff --git a/tests/compiler/dart2js/type_inference8_test.dart b/tests/compiler/dart2js/type_inference8_test.dart
index fb4717c..bc629d8 100644
--- a/tests/compiler/dart2js/type_inference8_test.dart
+++ b/tests/compiler/dart2js/type_inference8_test.dart
@@ -34,8 +34,8 @@
Uri uri = new Uri(scheme: 'source');
var compiler = compilerFor(TEST1, uri);
return compiler.run(uri).then((_) {
- var commonMasks = compiler.closedWorld.commonMasks;
var typesInferrer = compiler.globalInference.typesInferrerInternal;
+ var commonMasks = typesInferrer.closedWorld.commonMasks;
var element = findElement(compiler, "foo");
var mask = typesInferrer.getReturnTypeOfElement(element);
var falseType =
@@ -77,8 +77,8 @@
Uri uri = new Uri(scheme: 'source');
var compiler = compilerFor(TEST2, uri);
return compiler.run(uri).then((_) {
- var commonMasks = compiler.closedWorld.commonMasks;
var typesInferrer = compiler.globalInference.typesInferrerInternal;
+ var commonMasks = typesInferrer.closedWorld.commonMasks;
var element = findElement(compiler, "foo");
var mask = typesInferrer.getReturnTypeOfElement(element);
// Can't infer value for foo's return type, it could be either true or false
diff --git a/tests/compiler/dart2js/type_inference_switch_test.dart b/tests/compiler/dart2js/type_inference_switch_test.dart
index 181fc41..f28444b 100644
--- a/tests/compiler/dart2js/type_inference_switch_test.dart
+++ b/tests/compiler/dart2js/type_inference_switch_test.dart
@@ -133,17 +133,18 @@
Future runTest(String test, checker) {
Uri uri = new Uri(scheme: 'source');
var compiler = compilerFor(test, uri);
-
- checkTypeOf(String name, TypeMask type) {
- var commonMasks = compiler.closedWorld.commonMasks;
- var typesInferrer = compiler.globalInference.typesInferrerInternal;
- var element = findElement(compiler, name);
- var mask = typesInferrer.getReturnTypeOfElement(element);
- Expect.equals(type, simplify(mask, compiler));
- }
-
return compiler.run(uri).then((_) {
- checker(compiler.closedWorld.commonMasks, checkTypeOf);
+ var typesInferrer = compiler.globalInference.typesInferrerInternal;
+ var closedWorld = typesInferrer.closedWorld;
+ var commonMasks = closedWorld.commonMasks;
+
+ checkTypeOf(String name, TypeMask type) {
+ var element = findElement(compiler, name);
+ var mask = typesInferrer.getReturnTypeOfElement(element);
+ Expect.equals(type, simplify(mask, closedWorld));
+ }
+
+ checker(commonMasks, checkTypeOf);
});
}
diff --git a/tests/compiler/dart2js/type_mask2_test.dart b/tests/compiler/dart2js/type_mask2_test.dart
index 78791cb..609cac7 100644
--- a/tests/compiler/dart2js/type_mask2_test.dart
+++ b/tests/compiler/dart2js/type_mask2_test.dart
@@ -104,7 +104,7 @@
""",
useMockCompiler: false);
- ClosedWorld closedWorld = env.compiler.closedWorld;
+ ClosedWorld closedWorld = env.closedWorld;
ClassElement Object_ = env.getElement("Object");
ClassElement A = env.getElement("A");
@@ -213,12 +213,11 @@
}
""",
useMockCompiler: false);
- var closedWorld = env.compiler.closedWorld;
- var backend = env.compiler.backend;
+ ClosedWorld closedWorld = env.closedWorld;
ClassElement Object_ = env.getElement("Object");
ClassElement String_ = env.getElement("String");
- ClassElement JSString = backend.helpers.jsStringClass;
+ ClassElement JSString = closedWorld.backendClasses.stringImplementation;
List<ClassElement> allClasses = <ClassElement>[Object_, String_];
diff --git a/tests/compiler/dart2js/type_mask_disjoint_test.dart b/tests/compiler/dart2js/type_mask_disjoint_test.dart
index 7c643a5..928bedf 100644
--- a/tests/compiler/dart2js/type_mask_disjoint_test.dart
+++ b/tests/compiler/dart2js/type_mask_disjoint_test.dart
@@ -36,7 +36,7 @@
Uri uri = new Uri(scheme: 'source');
var compiler = compilerFor(CODE, uri);
-var world = compiler.closedWorld;
+var world = compiler.resolverWorld.closedWorldForTesting;
main() {
asyncTest(() => compiler.run(uri).then((_) {
diff --git a/tests/compiler/dart2js/type_mask_test.dart b/tests/compiler/dart2js/type_mask_test.dart
index 16bf898..fd197f1 100644
--- a/tests/compiler/dart2js/type_mask_test.dart
+++ b/tests/compiler/dart2js/type_mask_test.dart
@@ -22,7 +22,7 @@
Uri uri = new Uri(scheme: 'source');
var compiler = compilerFor(CODE, uri);
compiler.closeResolution();
- var closedWorld = compiler.closedWorld;
+ var closedWorld = compiler.resolverWorld.closedWorldForTesting;
asyncTest(() => compiler.run(uri).then((_) {
var classA = findElement(compiler, 'A');
diff --git a/tests/compiler/dart2js/type_mask_test_helper.dart b/tests/compiler/dart2js/type_mask_test_helper.dart
index a6c8604..414d259 100644
--- a/tests/compiler/dart2js/type_mask_test_helper.dart
+++ b/tests/compiler/dart2js/type_mask_test_helper.dart
@@ -5,13 +5,13 @@
library type_mask_test_helper;
import 'package:compiler/src/types/types.dart';
-import 'package:compiler/src/compiler.dart' show Compiler;
+import 'package:compiler/src/world.dart' show ClosedWorld;
-TypeMask simplify(TypeMask mask, Compiler compiler) {
+TypeMask simplify(TypeMask mask, ClosedWorld closedWorld) {
if (mask is ForwardingTypeMask) {
- return simplify(mask.forwardTo, compiler);
+ return simplify(mask.forwardTo, closedWorld);
} else if (mask is UnionTypeMask) {
- return UnionTypeMask.flatten(mask.disjointMasks, compiler.closedWorld);
+ return UnionTypeMask.flatten(mask.disjointMasks, closedWorld);
} else {
return mask;
}
diff --git a/tests/compiler/dart2js/type_representation_test.dart b/tests/compiler/dart2js/type_representation_test.dart
index 2b16579..bb1280d 100644
--- a/tests/compiler/dart2js/type_representation_test.dart
+++ b/tests/compiler/dart2js/type_representation_test.dart
@@ -41,6 +41,8 @@
m9(int a, String b, {List<int> c, d}) {}
m10(void f(int a, [b])) {}
""").then((env) {
+ var closedWorld = env.compiler.closeResolution();
+ env.compiler.backend.onCodegenStart(closedWorld);
TypeRepresentationGenerator typeRepresentation =
new TypeRepresentationGenerator(env.compiler);
diff --git a/tests/compiler/dart2js/type_test_helper.dart b/tests/compiler/dart2js/type_test_helper.dart
index cc0ae90..0b215ac 100644
--- a/tests/compiler/dart2js/type_test_helper.dart
+++ b/tests/compiler/dart2js/type_test_helper.dart
@@ -14,6 +14,7 @@
import 'package:compiler/src/compiler.dart' show Compiler;
import 'package:compiler/src/elements/elements.dart'
show Element, MemberElement, TypeDeclarationElement, ClassElement;
+import 'package:compiler/src/world.dart' show ClosedWorld;
GenericType instantiate(
TypeDeclarationElement element, List<DartType> arguments) {
@@ -139,4 +140,8 @@
return new FunctionType.synthesized(returnType, parameters,
optionalParameters, namedParameterNames, namedParameterTypes);
}
+
+ ClosedWorld get closedWorld {
+ return compiler.resolverWorld.closedWorldForTesting;
+ }
}
diff --git a/tests/compiler/dart2js/union_type_test.dart b/tests/compiler/dart2js/union_type_test.dart
index 8294d47..243a066 100644
--- a/tests/compiler/dart2js/union_type_test.dart
+++ b/tests/compiler/dart2js/union_type_test.dart
@@ -23,7 +23,7 @@
""",
useMockCompiler: false);
env.compiler.closeResolution();
- ClosedWorld world = env.compiler.closedWorld;
+ ClosedWorld world = env.closedWorld;
FlatTypeMask mask1 = new FlatTypeMask.exact(env.getElement('A'));
FlatTypeMask mask2 = new FlatTypeMask.exact(env.getElement('B'));
UnionTypeMask union1 = mask1.nonNullable().union(mask2, world);
diff --git a/tests/compiler/dart2js/world_test.dart b/tests/compiler/dart2js/world_test.dart
index 4e29307..b8f49f9 100644
--- a/tests/compiler/dart2js/world_test.dart
+++ b/tests/compiler/dart2js/world_test.dart
@@ -49,7 +49,7 @@
}
""",
useMockCompiler: false);
- ClosedWorld closedWorld = env.compiler.closedWorld;
+ ClosedWorld closedWorld = env.closedWorld;
ClassElement Object_ = env.getElement("Object");
ClassElement A = env.getElement("A");
@@ -69,7 +69,7 @@
foundClasses.contains(expectedClass),
"Expect $expectedClass in '$property' on $cls. "
"Found:\n ${foundClasses.join('\n ')}\n"
- "${env.compiler.closedWorld.dump(cls)}");
+ "${closedWorld.dump(cls)}");
}
if (exact) {
Expect.equals(
@@ -78,7 +78,7 @@
"Unexpected classes "
"${foundClasses.where((c) => !expectedClasses.contains(c))} "
"in '$property' on $cls.\n"
- "${env.compiler.closedWorld.dump(cls)}");
+ "${closedWorld.dump(cls)}");
}
}
@@ -104,7 +104,7 @@
expectedClasses.length,
count,
"Unexpected class count in '$property' on $cls.\n"
- "${env.compiler.closedWorld.dump(cls)}");
+ "${closedWorld.dump(cls)}");
}
}
@@ -239,7 +239,7 @@
}
""",
useMockCompiler: false);
- ClosedWorld closedWorld = env.compiler.closedWorld;
+ ClosedWorld closedWorld = env.closedWorld;
check(String name, {bool hasStrictSubtype, bool hasOnlySubclasses}) {
ClassElement cls = env.getElement(name);
@@ -316,7 +316,7 @@
}
""",
useMockCompiler: false);
- ClosedWorld closedWorld = env.compiler.closedWorld;
+ ClosedWorld closedWorld = env.closedWorld;
LibraryElement dart_html =
env.compiler.libraryLoader.lookupLibrary(Uris.dart_html);
diff --git a/tests/html/html.status b/tests/html/html.status
index 23ec5b1..1907711 100644
--- a/tests/html/html.status
+++ b/tests/html/html.status
@@ -45,9 +45,9 @@
custom/element_upgrade_test: Fail # Issue 17298
[ $compiler == dart2js && $browser ]
+worker_api_test: RuntimeError # Issue 28155
custom/created_callback_test: Fail # Support for created constructor. Issue 14835
fontface_loaded_test: Fail # Support for promises.
-js_test/JsArray: RuntimeError # Issue 26197
[ $compiler == dart2js && ($runtime == safari || $runtime == safarimobilesim || $runtime == ff || $ie) ]
custom/entered_left_view_test/viewless_document: Fail # Polyfill does not handle this
@@ -323,7 +323,6 @@
indexeddb_5_test: RuntimeError # Issue 21433
-js_test/JsArray: RuntimeError # Fails 10 out of 10.
indexeddb_3_test: Skip # Times out 1 out of 10.
[ $compiler == dart2js && $runtime == ff ]
diff --git a/tests/html/js_test.dart b/tests/html/js_test.dart
index c554081..c429cd8 100644
--- a/tests/html/js_test.dart
+++ b/tests/html/js_test.dart
@@ -515,8 +515,6 @@
test('pass Array to JS', () {
context['a'] = [1, 2, 3];
- expect(context.callMethod('isPropertyInstanceOf',
- ['a', context['Array']]), isTrue);
var a = context['a'];
expect(a, new isInstanceOf<List>());
expect(a, isNot(new isInstanceOf<JsArray>()));
diff --git a/tests/language/config_import_corelib_general.dart b/tests/language/config_import_corelib_general.dart
new file mode 100644
index 0000000..04d3b5c
--- /dev/null
+++ b/tests/language/config_import_corelib_general.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2015, 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.
+
+class Classy {
+ String get name => "classy general";
+}
+
+bool general() => true;
+final String name = "general";
diff --git a/tests/language/config_import_corelib_http.dart b/tests/language/config_import_corelib_http.dart
new file mode 100644
index 0000000..292e091
--- /dev/null
+++ b/tests/language/config_import_corelib_http.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2015, 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:http";
+
+class Classy {
+ String get name => "classy http";
+ String httpSpecific() => "classy http";
+}
+
+bool general() => true;
+bool httpSpecific() => true;
+final String name = "http";
diff --git a/tests/language/config_import_corelib_io.dart b/tests/language/config_import_corelib_io.dart
new file mode 100644
index 0000000..d5b594a
--- /dev/null
+++ b/tests/language/config_import_corelib_io.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:io";
+
+class Classy {
+ String get name => "classy io";
+ String ioSpecific() => "classy io";
+}
+
+bool general() => true;
+bool ioSpecific() => true;
+final String name = "io";
diff --git a/tests/language/config_import_corelib_test.dart b/tests/language/config_import_corelib_test.dart
new file mode 100644
index 0000000..6536426
--- /dev/null
+++ b/tests/language/config_import_corelib_test.dart
@@ -0,0 +1,53 @@
+// Copyright (c) 2015, 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';
+
+import 'config_import_corelib_general.dart'
+ if (dart.library.io) 'config_import_corelib_io.dart'
+ if (dart.library.http) 'config_import_corelib_http.dart'
+ as lib;
+
+class SubClassy extends lib.Classy {
+ String get superName => super.name;
+}
+
+main() {
+ var io = const bool.fromEnvironment("dart.library.io");
+ var http = const bool.fromEnvironment("dart.library.http");
+
+ var cy = new SubClassy();
+
+ if (io) {
+ Expect.isTrue(lib.general());
+ Expect.equals("io", lib.name);
+ Expect.equals("classy io", cy.name);
+
+ Expect.isTrue(lib.ioSpecific());
+ Expect.equals("classy io", cy.ioSpecific());
+
+ Expect.throws(() { lib.httpSpecific(); });
+ Expect.throws(() { cy.httpSpecific(); });
+ } else if (http) {
+ Expect.isTrue(lib.general());
+ Expect.equals("http", lib.name);
+ Expect.equals("classy http", cy.name);
+
+ Expect.throws(() { lib.ioSpecific(); });
+ Expect.throws(() { cy.ioSpecific(); });
+
+ Expect.isTrue(lib.httpSpecific());
+ Expect.equals("classy http", cy.httpSpecific());
+ } else {
+ Expect.isTrue(lib.general());
+ Expect.equals("general", lib.name);
+ Expect.equals("classy general", cy.name);
+
+ Expect.throws(() { lib.ioSpecific(); });
+ Expect.throws(() { cy.ioSpecific(); });
+
+ Expect.throws(() { lib.httpSpecific(); });
+ Expect.throws(() { cy.httpSpecific(); });
+ }
+}
diff --git a/tests/language/language.status b/tests/language/language.status
index 371db4d..0cf4670 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -322,3 +322,4 @@
[$compiler == dart2analyzer]
vm/regress_27201_test: SkipByDesign # Loads bad library, so will always crash.
+config_import_corelib_test: StaticWarning, OK
diff --git a/tests/language/language_kernel.status b/tests/language/language_kernel.status
index 66c30ef7..a3730b6 100644
--- a/tests/language/language_kernel.status
+++ b/tests/language/language_kernel.status
@@ -95,6 +95,7 @@
# dartk: JIT failures
[ $compiler == dartk && $runtime == vm ]
+config_import_corelib_test: RuntimeError
enum_syntax_test/05: MissingCompileTimeError
reify_typevar_static_test/00: MissingCompileTimeError
type_variable_conflict2_test/06: MissingCompileTimeError
@@ -103,6 +104,7 @@
# dartk: precompilation failures
[ $compiler == dartkp && $runtime == dart_precompiled ]
+config_import_corelib_test: RuntimeError
###############################################################################
@@ -349,7 +351,6 @@
[ $compiler == dartk && $runtime == vm && $mode == debug ]
async_star_regression_fisk_test: Crash # Stack mismatch during expression translation.
async_star_test: Crash # Stack mismatch during expression translation.
-generic_sends_test: Crash
issue23244_test: Crash # Class finalization issue
not_enough_positional_arguments_test/02: Crash
not_enough_positional_arguments_test/05: Crash
@@ -379,6 +380,5 @@
# dartk: precompilation failures (debug)
[ $compiler == dartkp && $runtime == dart_precompiled && $mode == debug ]
constructor_named_arguments_test/01: Crash
-generic_sends_test: Crash
not_enough_positional_arguments_test/05: Crash
-enum_syntax_test/05: Crash
+enum_syntax_test/05: Crash
\ No newline at end of file
diff --git a/tests/language/vm/lazy_deopt_vm_test.dart b/tests/language/vm/lazy_deopt_vm_test.dart
new file mode 100644
index 0000000..a10242a
--- /dev/null
+++ b/tests/language/vm/lazy_deopt_vm_test.dart
@@ -0,0 +1,38 @@
+// 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.
+// VMOptions=--deoptimize_every=10 --optimization-counter-threshold=10 --no-background-compilation
+
+// Test that lazy deoptimization on stack checks does not damage unoptimized
+// frame.
+
+import 'package:expect/expect.dart';
+
+
+foo() {
+ var a = 0;
+ var b = 1;
+ var c = 2;
+ var d = 3;
+ var e = 4;
+ for (var i = 0; i < 10; i++) {
+ a++;
+ b++;
+ c++;
+ d++;
+ e++;
+ }
+ Expect.equals(10, a);
+ Expect.equals(11, b);
+ Expect.equals(12, c);
+ Expect.equals(13, d);
+ Expect.equals(14, e);
+}
+
+main() {
+ for (var i = 0; i < 10; ++i) {
+ foo();
+ }
+}
+
+
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index 3857327..3d000bd 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -269,7 +269,7 @@
async/future_or_bad_type_test/00: RuntimeError # Issue 28010
async/future_or_bad_type_test/01: RuntimeError # Issue 28010
-async/future_or_bad_type_test/implements: MissingCompileTimeError # Issue 28010
+async/future_or_bad_type_test/implements: Fail # Issue 28010
async/future_or_non_strong_test: RuntimeError # Issue 28010
async/future_or_strong_test: RuntimeError, OK
diff --git a/tests/lib_strong/html/js_test.dart b/tests/lib_strong/html/js_test.dart
index 675ddde..55b6eef 100644
--- a/tests/lib_strong/html/js_test.dart
+++ b/tests/lib_strong/html/js_test.dart
@@ -3,9 +3,10 @@
// BSD-style license that can be found in the LICENSE file.
import 'dart:html';
-import 'dart:typed_data' show ByteBuffer, Int32List;
+import 'dart:typed_data' show Int32List;
import 'dart:indexed_db' show IdbFactory, KeyRange;
import 'dart:js';
+import 'package:js/js_util.dart' as js_util;
import 'package:expect/minitest.dart';
@@ -508,8 +509,6 @@
test('pass Array to JS', () {
context['a'] = [1, 2, 3];
- expect(context.callMethod('isPropertyInstanceOf',
- ['a', context['Array']]), isTrue);
var a = context['a'];
expect(a is List, isTrue);
expect(a is JsArray, isFalse);
@@ -842,8 +841,6 @@
expect(context['window'] is Window, isTrue);
});
- // Bug: dartbug.com/24520
- /*
test('foreign browser objects should be proxied', () {
var iframe = new IFrameElement();
document.body.children.add(iframe);
@@ -851,26 +848,48 @@
// Window
var contentWindow = proxy['contentWindow'];
- expect(contentWindow, isNot(new isInstanceOf<Window>()));
- expect(contentWindow, new isInstanceOf<JsObject>());
+ expect(contentWindow is! Window, isTrue);
+ expect(contentWindow is JsObject, isTrue);
// Node
var foreignDoc = contentWindow['document'];
- expect(foreignDoc, isNot(new isInstanceOf<Node>()));
- expect(foreignDoc, new isInstanceOf<JsObject>());
+ expect(foreignDoc is! Node, isTrue);
+ expect(foreignDoc is JsObject, isTrue);
// Event
var clicked = false;
foreignDoc['onclick'] = (e) {
- expect(e, isNot(new isInstanceOf<Event>()));
- expect(e, new isInstanceOf<JsObject>());
+ expect(e is! Event, isTrue);
+ expect(e is JsObject, isTrue);
clicked = true;
};
context.callMethod('fireClickEvent', [contentWindow]);
expect(clicked, isTrue);
});
- */
+
+ test('foreign functions pass function is checks', () {
+ var iframe = new IFrameElement();
+ document.body.children.add(iframe);
+ var proxy = new JsObject.fromBrowserObject(iframe);
+
+ var contentWindow = proxy['contentWindow'];
+ var foreignDoc = contentWindow['document'];
+
+ // Function
+ var foreignFunction = foreignDoc['createElement'];
+ expect(foreignFunction is JsFunction, isTrue);
+
+ // Verify that internal isChecks in callMethod work.
+ foreignDoc.callMethod('createElement', ['div']);
+
+ var typedContentWindow = js_util.getProperty(iframe, 'contentWindow');
+ var typedForeignDoc = js_util.getProperty(typedContentWindow, 'document');
+
+ var typedForeignFunction = js_util.getProperty(typedForeignDoc, 'createElement');
+ expect(typedForeignFunction is Function, isTrue);
+ js_util.callMethod(typedForeignDoc, 'createElement', ['div']);
+ });
test('document', () {
expect(context['document'] is Document, isTrue);
diff --git a/tests/standalone/io/directory_test.dart b/tests/standalone/io/directory_test.dart
index 14685b1..dd86dc6 100644
--- a/tests/standalone/io/directory_test.dart
+++ b/tests/standalone/io/directory_test.dart
@@ -603,14 +603,27 @@
Expect.isTrue(temp2.existsSync());
Expect.equals(temp3.path, temp2.path);
- temp2.rename(temp1.path).then((temp4) {
- Expect.isFalse(temp3.existsSync());
- Expect.isFalse(temp2.existsSync());
- Expect.isTrue(temp1.existsSync());
- Expect.isTrue(temp4.existsSync());
- Expect.equals(temp1.path, temp4.path);
- temp1.deleteSync(recursive: true);
- });
+ var temp4 = temp2.renameSync(temp1.path);
+ Expect.isFalse(temp3.existsSync());
+ Expect.isFalse(temp2.existsSync());
+ Expect.isTrue(temp1.existsSync());
+ Expect.isTrue(temp4.existsSync());
+ Expect.equals(temp1.path, temp4.path);
+
+ String foo = '${temp4.path}/foo';
+ String bar = '${temp4.path}/bar';
+ new File(foo).createSync();
+ try {
+ new Directory(foo).renameSync(bar);
+ Expect.fail('Directory.rename should fail to rename a non-directory');
+ } catch (e) {
+ Expect.isTrue(e is FileSystemException);
+ if (Platform.isLinux || Platform.isMacOS) {
+ Expect.isTrue(e.osError.message.contains('Not a directory'));
+ }
+ }
+
+ temp1.deleteSync(recursive: true);
}
main() {
diff --git a/tools/VERSION b/tools/VERSION
index 9a61a77..08e0575 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -1,4 +1,3 @@
-
# This file is used by tools/utils.py to generate version strings.
# The numbers are changed as follows:
#
@@ -28,5 +27,5 @@
MAJOR 1
MINOR 22
PATCH 0
-PRERELEASE 2
+PRERELEASE 3
PRERELEASE_PATCH 0
diff --git a/tools/dom/templates/html/impl/impl_Blob.darttemplate b/tools/dom/templates/html/impl/impl_Blob.darttemplate
index e2617c2..62ac4c70 100644
--- a/tools/dom/templates/html/impl/impl_Blob.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Blob.darttemplate
@@ -20,8 +20,8 @@
return _create_2(blobParts, bag);
}
- static _create_1(parts) => JS('Blob', 'new Blob(#)', parts);
- static _create_2(parts, bag) => JS('Blob', 'new Blob(#, #)', parts, bag);
+ static _create_1(parts) => JS('Blob', 'new window.Blob(#)', parts);
+ static _create_2(parts, bag) => JS('Blob', 'new window.Blob(#, #)', parts, bag);
static _create_bag() => JS('var', '{}');
static _bag_set(bag, key, value) { JS('void', '#[#] = #', bag, key, value); }