Version 2.17.0-108.0.dev
Merge commit '447e802aaa653223903fe0b2a0dd00392e830072' into 'dev'
diff --git a/pkg/compiler/README.md b/pkg/compiler/README.md
index a0c6462..bf2c604 100644
--- a/pkg/compiler/README.md
+++ b/pkg/compiler/README.md
@@ -265,21 +265,7 @@
* `lib/src/compiler.dart`: defines the core `Compiler` object, which contains
all the logic about what the compiler pipeline does and how data is organized
- and communicated between different phases. For a long time, `Compiler` was
- also used throughout the system as a global dependency-injection object.
- We've been slowly disentangling those dependencies, but there are still many
- references to `compiler` still in use.
-
-* `lib/src/apiimpl.dart`: defines `CompilerImpl` a subclass of `Compiler` that
- adds support for loading scripts, resolving package URIs and patch files. The
- separation here is a bit historical and we should be able to remove it. It was
- added to make it easier to create a `MockCompiler` implementation for unit
- testing. The `MockCompiler` has been replaced in most unit tests by a regular
- `CompilerImpl` that uses a mock of the file-system (see
- `pkg/compiler/test/memory_compiler.dart`).
-
- AI: Once all tests are migrated to this memory compiler, we should merge
- `Compiler` and `CompilerImpl` and remove this file.
+ and communicated between different phases.
* `lib/src/closure.dart`: closures are compiled as classes, this file has the
logic to do this kind of conversion in the Dart element model. This includes
diff --git a/pkg/compiler/lib/compiler.dart b/pkg/compiler/lib/compiler.dart
index c90854f..b9ade95 100644
--- a/pkg/compiler/lib/compiler.dart
+++ b/pkg/compiler/lib/compiler.dart
@@ -8,7 +8,7 @@
import 'package:front_end/src/api_unstable/dart2js.dart' as fe;
-import 'src/apiimpl.dart';
+import 'src/compiler.dart';
import 'src/options.dart' show CompilerOptions;
// Unless explicitly allowed, passing [:null:] for any argument to the
@@ -242,7 +242,7 @@
throw new ArgumentError("compilerOutput must be non-null");
}
- CompilerImpl compiler = new CompilerImpl(
+ var compiler = Compiler(
compilerInput, compilerOutput, compilerDiagnostics, compilerOptions);
return compiler.run().then((bool success) {
return new CompilationResult(compiler,
diff --git a/pkg/compiler/lib/src/apiimpl.dart b/pkg/compiler/lib/src/apiimpl.dart
deleted file mode 100644
index 3759604..0000000
--- a/pkg/compiler/lib/src/apiimpl.dart
+++ /dev/null
@@ -1,216 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library leg_apiimpl;
-
-import 'dart:async';
-
-import '../compiler.dart' as api;
-import 'common/metrics.dart' show Metrics, Metric;
-import 'common/tasks.dart' show GenericTask, Measurer;
-import 'common.dart';
-import 'compiler.dart';
-import 'diagnostics/messages.dart' show Message;
-import 'environment.dart';
-import 'options.dart' show CompilerOptions;
-
-/// Implements the [Compiler] using a [api.CompilerInput] for supplying the
-/// sources.
-class CompilerImpl extends Compiler {
- @override
- final Measurer measurer;
- @override
- api.CompilerInput provider;
- api.CompilerDiagnostics handler;
-
- GenericTask userHandlerTask;
- GenericTask userProviderTask;
-
- CompilerImpl(this.provider, api.CompilerOutput outputProvider, this.handler,
- CompilerOptions options,
- {MakeReporterFunction makeReporter})
- // NOTE: allocating measurer is done upfront to ensure the wallclock is
- // started before other computations.
- : measurer = Measurer(enableTaskMeasurements: options.verbose),
- super(
- options: options,
- outputProvider: outputProvider,
- environment: _Environment(options.environment),
- makeReporter: makeReporter) {
- tasks.addAll([
- userHandlerTask = GenericTask('Diagnostic handler', measurer),
- userProviderTask = GenericTask('Input provider', measurer),
- ]);
- }
-
- void logInfo(String message) {
- callUserHandler(null, null, null, null, message, api.Diagnostic.INFO);
- }
-
- void logVerbose(String message) {
- callUserHandler(
- null, null, null, null, message, api.Diagnostic.VERBOSE_INFO);
- }
-
- @override
- Future<bool> run() {
- Duration setupDuration = measurer.elapsedWallClock;
- return selfTask.measureSubtask("impl.run", () async {
- bool success = await super.run();
- if (options.verbose) {
- StringBuffer timings = StringBuffer();
- computeTimings(setupDuration, timings);
- logVerbose('$timings');
- }
- if (options.reportPrimaryMetrics || options.reportSecondaryMetrics) {
- StringBuffer metrics = StringBuffer();
- collectMetrics(metrics);
- logInfo('$metrics');
- }
- return success;
- });
- }
-
- String _formatMs(int ms) {
- return (ms / 1000).toStringAsFixed(3) + 's';
- }
-
- void computeTimings(Duration setupDuration, StringBuffer timings) {
- timings.writeln("Timings:");
- Duration totalDuration = measurer.elapsedWallClock;
- Duration asyncDuration = measurer.elapsedAsyncWallClock;
- Duration cumulatedDuration = Duration.zero;
- List<_TimingData> timingData = [];
- for (final task in tasks) {
- String running = task.isRunning ? "*" : " ";
- Duration duration = task.duration;
- if (duration != Duration.zero) {
- cumulatedDuration += duration;
- int milliseconds = duration.inMilliseconds;
- timingData.add(_TimingData(' $running${task.name}:', milliseconds,
- milliseconds * 100 / totalDuration.inMilliseconds));
- for (String subtask in task.subtasks) {
- int subtime = task.getSubtaskTime(subtask);
- String running = task.getSubtaskIsRunning(subtask) ? "*" : " ";
- timingData.add(_TimingData(' $running${task.name} > $subtask:',
- subtime, subtime * 100 / totalDuration.inMilliseconds));
- }
- }
- }
- int longestDescription = timingData
- .map((d) => d.description.length)
- .fold(0, (a, b) => a < b ? b : a);
- for (var data in timingData) {
- var ms = _formatMs(data.milliseconds);
- var padding =
- " " * (longestDescription + 10 - data.description.length - ms.length);
- var percentPadding = data.percent < 10 ? " " : "";
- timings.writeln('${data.description}$padding $ms '
- '$percentPadding(${data.percent.toStringAsFixed(1)}%)');
- }
- Duration unaccountedDuration =
- totalDuration - cumulatedDuration - setupDuration - asyncDuration;
- double percent =
- unaccountedDuration.inMilliseconds * 100 / totalDuration.inMilliseconds;
- timings.write(
- ' Total compile-time ${_formatMs(totalDuration.inMilliseconds)};'
- ' setup ${_formatMs(setupDuration.inMilliseconds)};'
- ' async ${_formatMs(asyncDuration.inMilliseconds)};'
- ' unaccounted ${_formatMs(unaccountedDuration.inMilliseconds)}'
- ' (${percent.toStringAsFixed(2)}%)');
- }
-
- void collectMetrics(StringBuffer buffer) {
- buffer.writeln('Metrics:');
- for (final task in tasks) {
- Metrics metrics = task.metrics;
- String namespace = metrics.namespace;
- if (namespace == '') {
- namespace =
- task.name.toLowerCase().replaceAll(RegExp(r'[^a-z0-9]+'), '_');
- }
- void report(Metric metric) {
- buffer
- .writeln(' ${namespace}.${metric.name}: ${metric.formatValue()}');
- }
-
- for (final metric in metrics.primary) {
- report(metric);
- }
- if (options.reportSecondaryMetrics) {
- for (final metric in metrics.secondary) {
- report(metric);
- }
- }
- }
- }
-
- @override
- void reportDiagnostic(DiagnosticMessage message,
- List<DiagnosticMessage> infos, api.Diagnostic kind) {
- _reportDiagnosticMessage(message, kind);
- for (DiagnosticMessage info in infos) {
- _reportDiagnosticMessage(info, api.Diagnostic.INFO);
- }
- }
-
- void _reportDiagnosticMessage(
- DiagnosticMessage diagnosticMessage, api.Diagnostic kind) {
- // [:span.uri:] might be [:null:] in case of a [Script] with no [uri]. For
- // instance in the [Types] constructor in typechecker.dart.
- SourceSpan span = diagnosticMessage.sourceSpan;
- Message message = diagnosticMessage.message;
- if (span == null || span.uri == null) {
- callUserHandler(message, null, null, null, '$message', kind);
- } else {
- callUserHandler(
- message, span.uri, span.begin, span.end, '$message', kind);
- }
- }
-
- void callUserHandler(Message message, Uri uri, int begin, int end,
- String text, api.Diagnostic kind) {
- try {
- userHandlerTask.measure(() {
- handler.report(message, uri, begin, end, text, kind);
- });
- } catch (ex, s) {
- reportCrashInUserCode('Uncaught exception in diagnostic handler', ex, s);
- rethrow;
- }
- }
-
- Future<api.Input> callUserProvider(Uri uri, api.InputKind inputKind) {
- try {
- return userProviderTask
- .measureIo(() => provider.readFromUri(uri, inputKind: inputKind));
- } catch (ex, s) {
- reportCrashInUserCode('Uncaught exception in input provider', ex, s);
- rethrow;
- }
- }
-}
-
-class _Environment implements Environment {
- final Map<String, String> definitions;
- Map<String, String> _completeMap;
-
- _Environment(this.definitions);
-
- @override
- Map<String, String> toMap() {
- if (_completeMap == null) {
- _completeMap = Map<String, String>.from(definitions);
- }
- return _completeMap;
- }
-}
-
-class _TimingData {
- final String description;
- final int milliseconds;
- final double percent;
-
- _TimingData(this.description, this.milliseconds, this.percent);
-}
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index ad4f8c8..271c7c6 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -16,6 +16,7 @@
import 'common.dart';
import 'common/codegen.dart';
import 'common/elements.dart' show ElementEnvironment;
+import 'common/metrics.dart' show Metric;
import 'common/names.dart' show Selectors;
import 'common/tasks.dart' show CompilerTask, GenericTask, Measurer;
import 'common/work.dart' show WorkItem;
@@ -63,15 +64,19 @@
typedef MakeReporterFunction = CompilerDiagnosticReporter Function(
Compiler compiler, CompilerOptions options);
-abstract class Compiler {
- Measurer get measurer;
-
- api.CompilerInput get provider;
+/// Implementation of the compiler using a [api.CompilerInput] for supplying
+/// the sources.
+class Compiler {
+ final Measurer measurer;
+ final api.CompilerInput provider;
+ final api.CompilerDiagnostics handler;
FrontendStrategy frontendStrategy;
BackendStrategy backendStrategy;
CompilerDiagnosticReporter _reporter;
Map<Entity, WorldImpact> _impactCache;
+ GenericTask userHandlerTask;
+ GenericTask userProviderTask;
/// Options provided from command-line arguments.
final CompilerOptions options;
@@ -133,12 +138,12 @@
// Callback function used for testing codegen enqueuing.
void Function() onCodegenQueueEmptyForTesting;
- Compiler(
- {CompilerOptions options,
- api.CompilerOutput outputProvider,
- this.environment = const _EmptyEnvironment(),
- MakeReporterFunction makeReporter})
- : this.options = options {
+ Compiler(this.provider, this._outputProvider, this.handler, this.options,
+ {MakeReporterFunction makeReporter})
+ // NOTE: allocating measurer is done upfront to ensure the wallclock is
+ // started before other computations.
+ : measurer = Measurer(enableTaskMeasurements: options.verbose),
+ this.environment = Environment(options.environment) {
options.deriveOptions();
options.validate();
@@ -184,9 +189,10 @@
selfTask,
serializationTask = SerializationTask(
options, reporter, provider, outputProvider, measurer),
+ ...backendStrategy.tasks,
+ userHandlerTask = GenericTask('Diagnostic handler', measurer),
+ userProviderTask = GenericTask('Input provider', measurer)
];
-
- tasks.addAll(backendStrategy.tasks);
}
/// Creates the backend strategy.
@@ -220,8 +226,8 @@
// succeeded.
Future<bool> run() => selfTask.measureSubtask("run", () {
measurer.startWallClock();
-
- return Future.sync(() => runInternal())
+ var setupDuration = measurer.elapsedWallClock;
+ var success = Future.sync(() => runInternal())
.catchError((error, StackTrace stackTrace) =>
_reporter.onError(options.compilationTarget, error, stackTrace))
.whenComplete(() {
@@ -229,6 +235,17 @@
}).then((_) {
return !compilationFailed;
});
+ if (options.verbose) {
+ var timings = StringBuffer();
+ computeTimings(setupDuration, timings);
+ logVerbose('$timings');
+ }
+ if (options.reportPrimaryMetrics || options.reportSecondaryMetrics) {
+ var metrics = StringBuffer();
+ collectMetrics(metrics);
+ logInfo('$metrics');
+ }
+ return success;
});
bool get onlyPerformGlobalTypeInference {
@@ -640,7 +657,48 @@
}
void reportDiagnostic(DiagnosticMessage message,
- List<DiagnosticMessage> infos, api.Diagnostic kind);
+ List<DiagnosticMessage> infos, api.Diagnostic kind) {
+ _reportDiagnosticMessage(message, kind);
+ for (DiagnosticMessage info in infos) {
+ _reportDiagnosticMessage(info, api.Diagnostic.INFO);
+ }
+ }
+
+ void _reportDiagnosticMessage(
+ DiagnosticMessage diagnosticMessage, api.Diagnostic kind) {
+ // [:span.uri:] might be [:null:] in case of a [Script] with no [uri]. For
+ // instance in the [Types] constructor in typechecker.dart.
+ var span = diagnosticMessage.sourceSpan;
+ var message = diagnosticMessage.message;
+ if (span == null || span.uri == null) {
+ callUserHandler(message, null, null, null, '$message', kind);
+ } else {
+ callUserHandler(
+ message, span.uri, span.begin, span.end, '$message', kind);
+ }
+ }
+
+ void callUserHandler(Message message, Uri uri, int begin, int end,
+ String text, api.Diagnostic kind) {
+ try {
+ userHandlerTask.measure(() {
+ handler.report(message, uri, begin, end, text, kind);
+ });
+ } catch (ex, s) {
+ reportCrashInUserCode('Uncaught exception in diagnostic handler', ex, s);
+ rethrow;
+ }
+ }
+
+ Future<api.Input> callUserProvider(Uri uri, api.InputKind inputKind) {
+ try {
+ return userProviderTask
+ .measureIo(() => provider.readFromUri(uri, inputKind: inputKind));
+ } catch (ex, s) {
+ reportCrashInUserCode('Uncaught exception in input provider', ex, s);
+ rethrow;
+ }
+ }
void reportCrashInUserCode(String message, exception, stackTrace) {
reporter.onCrashInUserCode(message, exception, stackTrace);
@@ -733,6 +791,89 @@
}
return null;
}
+
+ void logInfo(String message) {
+ callUserHandler(null, null, null, null, message, api.Diagnostic.INFO);
+ }
+
+ void logVerbose(String message) {
+ callUserHandler(
+ null, null, null, null, message, api.Diagnostic.VERBOSE_INFO);
+ }
+
+ String _formatMs(int ms) {
+ return (ms / 1000).toStringAsFixed(3) + 's';
+ }
+
+ void computeTimings(Duration setupDuration, StringBuffer timings) {
+ timings.writeln("Timings:");
+ var totalDuration = measurer.elapsedWallClock;
+ var asyncDuration = measurer.elapsedAsyncWallClock;
+ var cumulatedDuration = Duration.zero;
+ var timingData = <_TimingData>[];
+ for (final task in tasks) {
+ var running = task.isRunning ? "*" : " ";
+ var duration = task.duration;
+ if (duration != Duration.zero) {
+ cumulatedDuration += duration;
+ var milliseconds = duration.inMilliseconds;
+ timingData.add(_TimingData(' $running${task.name}:', milliseconds,
+ milliseconds * 100 / totalDuration.inMilliseconds));
+ for (String subtask in task.subtasks) {
+ var subtime = task.getSubtaskTime(subtask);
+ var running = task.getSubtaskIsRunning(subtask) ? "*" : " ";
+ timingData.add(_TimingData(' $running${task.name} > $subtask:',
+ subtime, subtime * 100 / totalDuration.inMilliseconds));
+ }
+ }
+ }
+ int longestDescription = timingData
+ .map((d) => d.description.length)
+ .fold(0, (a, b) => a < b ? b : a);
+ for (var data in timingData) {
+ var ms = _formatMs(data.milliseconds);
+ var padding =
+ " " * (longestDescription + 10 - data.description.length - ms.length);
+ var percentPadding = data.percent < 10 ? " " : "";
+ timings.writeln('${data.description}$padding $ms '
+ '$percentPadding(${data.percent.toStringAsFixed(1)}%)');
+ }
+ var unaccountedDuration =
+ totalDuration - cumulatedDuration - setupDuration - asyncDuration;
+ var percent =
+ unaccountedDuration.inMilliseconds * 100 / totalDuration.inMilliseconds;
+ timings.write(
+ ' Total compile-time ${_formatMs(totalDuration.inMilliseconds)};'
+ ' setup ${_formatMs(setupDuration.inMilliseconds)};'
+ ' async ${_formatMs(asyncDuration.inMilliseconds)};'
+ ' unaccounted ${_formatMs(unaccountedDuration.inMilliseconds)}'
+ ' (${percent.toStringAsFixed(2)}%)');
+ }
+
+ void collectMetrics(StringBuffer buffer) {
+ buffer.writeln('Metrics:');
+ for (final task in tasks) {
+ var metrics = task.metrics;
+ var namespace = metrics.namespace;
+ if (namespace == '') {
+ namespace =
+ task.name.toLowerCase().replaceAll(RegExp(r'[^a-z0-9]+'), '_');
+ }
+ void report(Metric metric) {
+ buffer
+ .writeln(' ${namespace}.${metric.name}: ${metric.formatValue()}');
+ }
+
+ for (final metric in metrics.primary) {
+ report(metric);
+ }
+ if (options.reportSecondaryMetrics) {
+ for (final metric in metrics.secondary) {
+ report(metric);
+ }
+ }
+ }
+ }
}
class _CompilerOutput implements api.CompilerOutput {
@@ -1045,11 +1186,12 @@
}
}
-class _EmptyEnvironment implements Environment {
- const _EmptyEnvironment();
+class _TimingData {
+ final String description;
+ final int milliseconds;
+ final double percent;
- @override
- Map<String, String> toMap() => const {};
+ _TimingData(this.description, this.milliseconds, this.percent);
}
/// Interface for showing progress during compilation.
diff --git a/pkg/compiler/lib/src/environment.dart b/pkg/compiler/lib/src/environment.dart
index efc2bb0..cb5fdbd 100644
--- a/pkg/compiler/lib/src/environment.dart
+++ b/pkg/compiler/lib/src/environment.dart
@@ -7,7 +7,10 @@
/// Environment variables can be used in the user code in two ways. From
/// conditional imports, and from `const String.fromEnvironment` and
/// other similar constructors.
-abstract class Environment {
- /// Returns the full environment as map.
- Map<String, String> toMap();
+class Environment {
+ /// An immutable map of environment variables.
+ final Map<String, String> definitions;
+
+ Environment(Map<String, String> definitions)
+ : this.definitions = Map.unmodifiable(definitions);
}
diff --git a/pkg/compiler/lib/src/ir/constants.dart b/pkg/compiler/lib/src/ir/constants.dart
index d95ffb2..4ac13df 100644
--- a/pkg/compiler/lib/src/ir/constants.dart
+++ b/pkg/compiler/lib/src/ir/constants.dart
@@ -8,6 +8,7 @@
import 'package:kernel/src/printer.dart' as ir;
import 'package:kernel/type_environment.dart' as ir;
+import '../environment.dart';
import '../kernel/dart2js_target.dart';
typedef ReportErrorFunction = void Function(
@@ -20,7 +21,7 @@
Dart2jsConstantEvaluator(ir.Component component,
ir.TypeEnvironment typeEnvironment, ReportErrorFunction reportError,
- {Map<String, String> environment = const {},
+ {Environment environment,
bool supportReevaluationForTesting = false,
ir.EvaluationMode evaluationMode})
: _supportReevaluationForTesting = supportReevaluationForTesting,
@@ -29,7 +30,7 @@
const Dart2jsDartLibrarySupport(),
const Dart2jsConstantsBackend(supportsUnevaluatedConstants: false),
component,
- environment,
+ environment?.definitions ?? const {},
typeEnvironment,
ErrorReporter(reportError),
enableTripleShift: true,
diff --git a/pkg/compiler/lib/src/js_model/element_map_impl.dart b/pkg/compiler/lib/src/js_model/element_map_impl.dart
index 9ca6a7c..48f715e 100644
--- a/pkg/compiler/lib/src/js_model/element_map_impl.dart
+++ b/pkg/compiler/lib/src/js_model/element_map_impl.dart
@@ -1169,7 +1169,7 @@
(ir.LocatedMessage message, List<ir.LocatedMessage> context) {
reportLocatedMessage(reporter, message, context);
},
- environment: _environment.toMap(),
+ environment: _environment,
evaluationMode: options.useLegacySubtyping
? ir.EvaluationMode.weak
: ir.EvaluationMode.strong);
diff --git a/pkg/compiler/lib/src/kernel/element_map_impl.dart b/pkg/compiler/lib/src/kernel/element_map_impl.dart
index 99cc1e2..ba76698 100644
--- a/pkg/compiler/lib/src/kernel/element_map_impl.dart
+++ b/pkg/compiler/lib/src/kernel/element_map_impl.dart
@@ -811,7 +811,7 @@
(ir.LocatedMessage message, List<ir.LocatedMessage> context) {
reportLocatedMessage(reporter, message, context);
},
- environment: _environment.toMap(),
+ environment: _environment,
evaluationMode: options.useLegacySubtyping
? ir.EvaluationMode.weak
: ir.EvaluationMode.strong);
diff --git a/pkg/compiler/lib/src/source_file_provider.dart b/pkg/compiler/lib/src/source_file_provider.dart
index 894d7fc..4ab19c1 100644
--- a/pkg/compiler/lib/src/source_file_provider.dart
+++ b/pkg/compiler/lib/src/source_file_provider.dart
@@ -240,7 +240,7 @@
if (kind != api.Diagnostic.INFO) {
lastKind = kind;
}
- var color;
+ String Function(String) color;
if (kind == api.Diagnostic.ERROR) {
color = colors.red;
} else if (kind == api.Diagnostic.WARNING) {
diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart
index 139b3a2..ac66787 100644
--- a/pkg/compiler/lib/src/ssa/builder_kernel.dart
+++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
@@ -6347,7 +6347,7 @@
if (element == _commonElements.traceHelper) return;
// TODO(sigmund): create a better uuid for elements.
HConstant idConstant = graph.addConstantInt(element.hashCode, closedWorld);
- n(e) => e == null ? '' : e.name;
+ String n(Entity e) => e == null ? '' : e.name;
String name = "${n(element.library)}:${n(element.enclosingClass)}."
"${n(element)}";
HConstant nameConstant = graph.addConstantString(name, closedWorld);
@@ -6437,7 +6437,7 @@
kernelBuilder.open(startTryBlock);
}
- void _addExitTrySuccessor(successor) {
+ void _addExitTrySuccessor(HBasicBlock successor) {
if (successor == null) return;
// Iterate over all blocks created inside this try/catch, and
// attach successor information to blocks that end with
@@ -6451,7 +6451,7 @@
}
}
- void _addOptionalSuccessor(block1, block2) {
+ void _addOptionalSuccessor(HBasicBlock block1, HBasicBlock block2) {
if (block2 != null) block1.addSuccessor(block2);
}
diff --git a/pkg/compiler/lib/src/ssa/codegen_helpers.dart b/pkg/compiler/lib/src/ssa/codegen_helpers.dart
index 0d27a96..b1a37fb 100644
--- a/pkg/compiler/lib/src/ssa/codegen_helpers.dart
+++ b/pkg/compiler/lib/src/ssa/codegen_helpers.dart
@@ -1024,6 +1024,9 @@
if (!identical(end.predecessors[1], elseBlock)) return;
HPhi phi = end.phis.first;
+ // This useless phi should have been removed. Do not generate-at-use if
+ // there is no use. See #48383.
+ if (phi.usedBy.isEmpty) return;
HInstruction thenInput = phi.inputs[0];
HInstruction elseInput = phi.inputs[1];
if (thenInput.isJsStatement() || elseInput.isJsStatement()) return;
diff --git a/pkg/compiler/lib/src/ssa/optimize.dart b/pkg/compiler/lib/src/ssa/optimize.dart
index 5ef83e7..fe51fdd 100644
--- a/pkg/compiler/lib/src/ssa/optimize.dart
+++ b/pkg/compiler/lib/src/ssa/optimize.dart
@@ -2541,6 +2541,11 @@
}
void simplifyPhi(HPhi phi) {
+ // Remove an unused HPhi so that the inputs can become potentially dead.
+ if (phi.usedBy.isEmpty) {
+ phi.block.removePhi(phi);
+ return;
+ }
// If the phi is of the form `phi(x, HTypeKnown(x))`, it does not strengthen
// `x`. We can replace the phi with `x` to potentially make the HTypeKnown
// refinement node dead and potentially make a HIf control no HPhis.
diff --git a/pkg/compiler/lib/src/universe/side_effects.dart b/pkg/compiler/lib/src/universe/side_effects.dart
index c05eaf7..f4101839 100644
--- a/pkg/compiler/lib/src/universe/side_effects.dart
+++ b/pkg/compiler/lib/src/universe/side_effects.dart
@@ -58,7 +58,8 @@
}
@override
- bool operator ==(other) => _flags == other._flags;
+ bool operator ==(Object other) =>
+ other is SideEffects && _flags == other._flags;
@override
int get hashCode => throw UnsupportedError('SideEffects.hashCode');
diff --git a/pkg/compiler/lib/src/util/util.dart b/pkg/compiler/lib/src/util/util.dart
index 7c5f50b..c9fa382 100644
--- a/pkg/compiler/lib/src/util/util.dart
+++ b/pkg/compiler/lib/src/util/util.dart
@@ -160,8 +160,8 @@
/// anything which supports [:write:] and [:writeCharCode:], for example,
/// [StringBuffer]. Note that JS supports \xnn and \unnnn whereas JSON only
/// supports the \unnnn notation. Therefore we use the \unnnn notation.
-void writeJsonEscapedCharsOn(String string, buffer) {
- void addCodeUnitEscaped(var buffer, int code) {
+void writeJsonEscapedCharsOn(String string, StringBuffer buffer) {
+ void addCodeUnitEscaped(StringBuffer buffer, int code) {
assert(code < 0x10000);
buffer.write(r'\u');
if (code < 0x1000) {
@@ -176,7 +176,7 @@
buffer.write(code.toRadixString(16));
}
- void writeEscapedOn(String string, var buffer) {
+ void writeEscapedOn(String string, StringBuffer buffer) {
for (int i = 0; i < string.length; i++) {
int code = string.codeUnitAt(i);
if (code == $DQ) {
diff --git a/pkg/compiler/test/analyses/api_allowed.json b/pkg/compiler/test/analyses/api_allowed.json
index c54c832..645ff86 100644
--- a/pkg/compiler/test/analyses/api_allowed.json
+++ b/pkg/compiler/test/analyses/api_allowed.json
@@ -14,15 +14,11 @@
"org-dartlang-sdk:///lib/_http/websocket_impl.dart": {
"Dynamic invocation of 'dart._http::_toJSON'.": 1
},
- "org-dartlang-sdk:///lib/_internal/js_runtime/lib/js_number.dart": {
- "Dynamic invocation of '[]'.": 5
- },
"org-dartlang-sdk:///lib/_internal/js_runtime/lib/js_helper.dart": {
"Dynamic access of 'length'.": 1
},
"org-dartlang-sdk:///lib/_internal/js_runtime/lib/async_patch.dart": {
- "Dynamic access of 'iterator'.": 1,
- "Dynamic invocation of 'then'.": 1
+ "Dynamic access of 'iterator'.": 1
},
"org-dartlang-sdk:///lib/_internal/js_runtime/lib/convert_patch.dart": {
"Dynamic invocation of 'clear'.": 1
@@ -109,4 +105,4 @@
"org-dartlang-sdk:///lib/core/errors.dart": {
"Dynamic access of 'length'.": 2
}
-}
\ No newline at end of file
+}
diff --git a/pkg/compiler/test/analyses/dart2js_allowed.json b/pkg/compiler/test/analyses/dart2js_allowed.json
index 7f34cc7..ea447f6 100644
--- a/pkg/compiler/test/analyses/dart2js_allowed.json
+++ b/pkg/compiler/test/analyses/dart2js_allowed.json
@@ -4,13 +4,6 @@
"Dynamic invocation of 'resume'.": 1,
"Dynamic invocation of 'pause'.": 1
},
- "pkg/compiler/lib/src/source_file_provider.dart": {
- "Dynamic invocation of 'call'.": 3
- },
- "pkg/compiler/lib/src/util/util.dart": {
- "Dynamic invocation of 'write'.": 11,
- "Dynamic invocation of 'writeCharCode'.": 1
- },
"pkg/compiler/lib/src/util/maplet.dart": {
"Dynamic access of 'isEmpty'.": 1,
"Dynamic access of 'length'.": 1,
@@ -85,14 +78,6 @@
"pkg/dart2js_info/lib/binary_serialization.dart": {
"Dynamic invocation of 'cast'.": 1
},
- "pkg/compiler/lib/src/universe/side_effects.dart": {
- "Dynamic access of 'universe.side_effects::_flags'.": 1
- },
- "pkg/compiler/lib/src/ssa/builder_kernel.dart": {
- "Dynamic access of 'name'.": 1,
- "Dynamic access of 'id'.": 1,
- "Dynamic invocation of 'addSuccessor'.": 1
- },
"pkg/compiler/lib/src/ssa/types.dart": {
"Dynamic access of 'element'.": 1
},
diff --git a/pkg/compiler/test/end_to_end/dill_loader_test.dart b/pkg/compiler/test/end_to_end/dill_loader_test.dart
index 6cf4fb9..6e22f60 100644
--- a/pkg/compiler/test/end_to_end/dill_loader_test.dart
+++ b/pkg/compiler/test/end_to_end/dill_loader_test.dart
@@ -6,7 +6,6 @@
import '../helpers/memory_compiler.dart';
import 'package:async_helper/async_helper.dart';
-import 'package:compiler/src/apiimpl.dart' show CompilerImpl;
import 'package:compiler/src/common/elements.dart';
import 'package:compiler/src/elements/entities.dart'
show LibraryEntity, ClassEntity;
@@ -38,7 +37,7 @@
List<int> kernelBinary =
serializeComponent((await kernelForProgram(uri, options)).component);
- CompilerImpl compiler = compilerFor(
+ var compiler = compilerFor(
entryPoint: uri,
memorySourceFiles: {'main.dill': kernelBinary},
diagnosticHandler: diagnostics,
diff --git a/pkg/compiler/test/end_to_end/exit_code_test.dart b/pkg/compiler/test/end_to_end/exit_code_test.dart
index 76920d1..ee7a324 100644
--- a/pkg/compiler/test/end_to_end/exit_code_test.dart
+++ b/pkg/compiler/test/end_to_end/exit_code_test.dart
@@ -22,7 +22,6 @@
import 'package:compiler/src/diagnostics/invariant.dart';
import 'package:compiler/src/diagnostics/messages.dart';
import 'package:compiler/src/diagnostics/spannable.dart';
-import 'package:compiler/src/apiimpl.dart';
import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/js_model/js_strategy.dart';
import 'package:compiler/src/null_compiler_output.dart';
@@ -33,7 +32,7 @@
import 'diagnostic_reporter_helper.dart';
import '../helpers/memory_compiler.dart';
-class TestCompiler extends CompilerImpl {
+class TestCompiler extends Compiler {
final String testMarker;
final String testType;
final Function onTest;
diff --git a/pkg/compiler/test/end_to_end/modular_loader_test.dart b/pkg/compiler/test/end_to_end/modular_loader_test.dart
index bc59954..00abbf1 100644
--- a/pkg/compiler/test/end_to_end/modular_loader_test.dart
+++ b/pkg/compiler/test/end_to_end/modular_loader_test.dart
@@ -6,7 +6,6 @@
import '../helpers/memory_compiler.dart';
import 'package:async_helper/async_helper.dart';
-import 'package:compiler/src/apiimpl.dart' show CompilerImpl;
import 'package:compiler/src/common/elements.dart';
import 'package:compiler/src/elements/entities.dart'
show LibraryEntity, ClassEntity;
@@ -35,7 +34,7 @@
DiagnosticCollector diagnostics = DiagnosticCollector();
OutputCollector output = OutputCollector();
Uri entryPoint = Uri.parse('org-dartlang-test:///c2.dart');
- CompilerImpl compiler = compilerFor(
+ var compiler = compilerFor(
entryPoint: entryPoint,
options: [
'--input-dill=memory:c.dill',
diff --git a/pkg/compiler/test/helpers/memory_compiler.dart b/pkg/compiler/test/helpers/memory_compiler.dart
index 0e3ed0c..7131e00 100644
--- a/pkg/compiler/test/helpers/memory_compiler.dart
+++ b/pkg/compiler/test/helpers/memory_compiler.dart
@@ -10,6 +10,7 @@
import 'package:compiler/compiler.dart'
show CompilationResult, CompilerDiagnostics, CompilerOutput, Diagnostic;
+import 'package:compiler/src/compiler.dart' show Compiler;
import 'package:compiler/src/common.dart';
import 'package:compiler/src/commandline_options.dart';
import 'package:compiler/src/diagnostics/messages.dart' show Message;
@@ -89,12 +90,12 @@
bool showDiagnostics: true,
Uri librariesSpecificationUri,
Uri packageConfig,
- void beforeRun(CompilerImpl compiler),
+ void beforeRun(Compiler compiler),
bool unsafeToTouchSourceFiles: false}) async {
if (entryPoint == null) {
entryPoint = Uri.parse('memory:main.dart');
}
- CompilerImpl compiler = compilerFor(
+ Compiler compiler = compilerFor(
entryPoint: entryPoint,
memorySourceFiles: memorySourceFiles,
diagnosticHandler: diagnosticHandler,
@@ -114,7 +115,7 @@
isSuccess: isSuccess, kernelInitializedCompilerState: compilerState);
}
-CompilerImpl compilerFor(
+Compiler compilerFor(
{Uri entryPoint,
Map<String, dynamic> memorySourceFiles: const <String, dynamic>{},
CompilerDiagnostics diagnosticHandler,
@@ -173,7 +174,7 @@
..packageConfig = packageConfig;
compilerOptions.kernelInitializedCompilerState =
kernelInitializedCompilerState;
- CompilerImpl compiler = new CompilerImpl(
+ var compiler = new Compiler(
provider, outputProvider, diagnosticHandler, compilerOptions);
return compiler;
diff --git a/pkg/compiler/test/helpers/memory_source_file_helper.dart b/pkg/compiler/test/helpers/memory_source_file_helper.dart
index 3591263..db35ef1 100644
--- a/pkg/compiler/test/helpers/memory_source_file_helper.dart
+++ b/pkg/compiler/test/helpers/memory_source_file_helper.dart
@@ -11,8 +11,6 @@
import 'package:compiler/compiler.dart';
-export 'package:compiler/src/apiimpl.dart' show CompilerImpl;
-
import 'package:compiler/src/io/source_file.dart'
show Binary, StringSourceFile, Utf8BytesSourceFile;
diff --git a/pkg/compiler/test/model/cfe_constant_evaluation_test.dart b/pkg/compiler/test/model/cfe_constant_evaluation_test.dart
index 693dccb..ae213d2 100644
--- a/pkg/compiler/test/model/cfe_constant_evaluation_test.dart
+++ b/pkg/compiler/test/model/cfe_constant_evaluation_test.dart
@@ -16,6 +16,7 @@
import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/elements/indexed.dart';
import 'package:compiler/src/elements/types.dart';
+import 'package:compiler/src/environment.dart';
import 'package:compiler/src/ir/constants.dart';
import 'package:compiler/src/ir/visitors.dart';
import 'package:compiler/src/kernel/kernel_strategy.dart';
@@ -606,7 +607,7 @@
errors.add(context.first.code.name);
reportLocatedMessage(elementMap.reporter, message, context);
},
- environment: environment,
+ environment: Environment(environment),
supportReevaluationForTesting: true,
evaluationMode: compiler.options.useLegacySubtyping
? ir.EvaluationMode.weak
diff --git a/pkg/compiler/test/sourcemaps/helpers/sourcemap_helper.dart b/pkg/compiler/test/sourcemaps/helpers/sourcemap_helper.dart
index 09a86fd..24ad0a3 100644
--- a/pkg/compiler/test/sourcemaps/helpers/sourcemap_helper.dart
+++ b/pkg/compiler/test/sourcemaps/helpers/sourcemap_helper.dart
@@ -9,8 +9,8 @@
import 'dart:async';
import 'dart:io';
import 'package:compiler/compiler.dart';
-import 'package:compiler/src/apiimpl.dart' as api;
import 'package:compiler/src/commandline_options.dart';
+import 'package:compiler/src/compiler.dart' as api;
import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/io/code_output.dart';
import 'package:compiler/src/io/source_file.dart';
@@ -357,7 +357,7 @@
throw "Compilation failed.";
}
- api.CompilerImpl compiler = result.compiler;
+ var compiler = result.compiler;
JsBackendStrategy backendStrategy = compiler.backendStrategy;
RecordingSourceInformationStrategy strategy =
backendStrategy.sourceInformationStrategy;
@@ -414,7 +414,7 @@
}
class SourceMaps {
- final api.CompilerImpl compiler;
+ final api.Compiler compiler;
final SourceFileManager sourceFileManager;
// TODO(johnniwinther): Supported multiple output units.
final SourceMapInfo mainSourceMapInfo;
diff --git a/pkg/dartdev/lib/src/templates/common.dart b/pkg/dartdev/lib/src/templates/common.dart
index ac53756..3c4a79c 100644
--- a/pkg/dartdev/lib/src/templates/common.dart
+++ b/pkg/dartdev/lib/src/templates/common.dart
@@ -4,9 +4,7 @@
import '../sdk.dart';
-String get sdkConstraint => '''
- sdk: '>=${sdk.version} <3.0.0'
-''';
+String get sdkConstraint => "sdk: '>=${sdk.version} <3.0.0'";
const String gitignore = '''
# Files and directories created by pub.
diff --git a/pkg/dartdev/lib/src/templates/console_full.dart b/pkg/dartdev/lib/src/templates/console_full.dart
index d4c2965..06583d9 100644
--- a/pkg/dartdev/lib/src/templates/console_full.dart
+++ b/pkg/dartdev/lib/src/templates/console_full.dart
@@ -38,7 +38,7 @@
# homepage: https://www.example.com
environment:
-${common.sdkConstraint}
+ ${common.sdkConstraint}
# dependencies:
# path: ^1.8.0
diff --git a/pkg/dartdev/lib/src/templates/console_simple.dart b/pkg/dartdev/lib/src/templates/console_simple.dart
index ed6f793..0234d18 100644
--- a/pkg/dartdev/lib/src/templates/console_simple.dart
+++ b/pkg/dartdev/lib/src/templates/console_simple.dart
@@ -36,7 +36,7 @@
# homepage: https://www.example.com
environment:
-${common.sdkConstraint}
+ ${common.sdkConstraint}
# dependencies:
# path: ^1.8.0
diff --git a/pkg/dartdev/lib/src/templates/package_simple.dart b/pkg/dartdev/lib/src/templates/package_simple.dart
index 9827dd7..6bdbd57 100644
--- a/pkg/dartdev/lib/src/templates/package_simple.dart
+++ b/pkg/dartdev/lib/src/templates/package_simple.dart
@@ -55,7 +55,7 @@
# homepage: https://www.example.com
environment:
-${common.sdkConstraint}
+ ${common.sdkConstraint}
# dependencies:
# path: ^1.8.0
diff --git a/pkg/dartdev/lib/src/templates/server_shelf.dart b/pkg/dartdev/lib/src/templates/server_shelf.dart
index c075f02..12a2e3b 100644
--- a/pkg/dartdev/lib/src/templates/server_shelf.dart
+++ b/pkg/dartdev/lib/src/templates/server_shelf.dart
@@ -42,7 +42,7 @@
# homepage: https://www.example.com
environment:
-${common.sdkConstraint}
+ ${common.sdkConstraint}
dependencies:
args: ^2.0.0
diff --git a/pkg/dartdev/lib/src/templates/web_simple.dart b/pkg/dartdev/lib/src/templates/web_simple.dart
index e22be74..04e8776 100644
--- a/pkg/dartdev/lib/src/templates/web_simple.dart
+++ b/pkg/dartdev/lib/src/templates/web_simple.dart
@@ -42,7 +42,7 @@
# homepage: https://www.example.com
environment:
-${common.sdkConstraint}
+ ${common.sdkConstraint}
# dependencies:
# path: ^1.7.0
diff --git a/runtime/tests/vm/dart/spawn_uri_aot_test.dart b/runtime/tests/vm/dart/spawn_uri_aot_test.dart
index ded95ce..44acb3a 100644
--- a/runtime/tests/vm/dart/spawn_uri_aot_test.dart
+++ b/runtime/tests/vm/dart/spawn_uri_aot_test.dart
@@ -55,11 +55,17 @@
''');
}
+ // '--enable-asserts' is not available in product mode, so we skip the
+ // negative test.
+ final isProductMode = const bool.fromEnvironment('dart.vm.product');
+
for (final basename in ['main', 'spawnee', 'spawnee_checked']) {
final script = path.join(dir, '$basename.dart');
final scriptDill = path.join(dir, '$basename.dart.dill');
final bool checked = basename.endsWith('_checked');
+ if (isProductMode && checked) continue;
+
await run(genKernel, <String>[
if (checked) '--enable-asserts',
'--aot',
@@ -89,18 +95,20 @@
'success',
], result1);
- // File exists and is AOT snapshot but was compiled with different flags
- // (namely --enable-asserts)
- final result2 = await runHelper(aotRuntime, [
- path.join(dir, 'main.dart.dill.so'),
- path.join(dir, 'spawnee_checked.dart.dill.so'),
- ]);
- Expect.notEquals(0, result2.exitCode);
- Expect.contains('Snapshot not compatible with the current VM configuration',
- result2.stderr);
+ if (!isProductMode) {
+ // File exists and is AOT snapshot but was compiled with different flags
+ // (namely --enable-asserts)
+ final result2 = await runHelper(aotRuntime, [
+ path.join(dir, 'main.dart.dill.so'),
+ path.join(dir, 'spawnee_checked.dart.dill.so'),
+ ]);
+ Expect.notEquals(0, result2.exitCode);
+ Expect.contains(
+ 'Snapshot not compatible with the current VM configuration',
+ result2.stderr);
+ }
- // File exists and is AOT snapshot but was compiled with different flags
- // (namely --enable-asserts)
+ // File does not exist.
final result3 = await runHelper(aotRuntime, [
path.join(dir, 'main.dart.dill.so'),
path.join(dir, 'does_not_exist.dart.dill.so'),
diff --git a/runtime/tests/vm/dart_2/spawn_uri_aot_test.dart b/runtime/tests/vm/dart_2/spawn_uri_aot_test.dart
index b3e3c21..ca4bd6a 100644
--- a/runtime/tests/vm/dart_2/spawn_uri_aot_test.dart
+++ b/runtime/tests/vm/dart_2/spawn_uri_aot_test.dart
@@ -57,11 +57,17 @@
''');
}
+ // '--enable-asserts' is not available in product mode, so we skip the
+ // negative test.
+ final isProductMode = const bool.fromEnvironment('dart.vm.product');
+
for (final basename in ['main', 'spawnee', 'spawnee_checked']) {
final script = path.join(dir, '$basename.dart');
final scriptDill = path.join(dir, '$basename.dart.dill');
final bool checked = basename.endsWith('_checked');
+ if (isProductMode && checked) continue;
+
await run(genKernel, <String>[
if (checked) '--enable-asserts',
'--aot',
@@ -91,18 +97,20 @@
'success',
], result1);
- // File exists and is AOT snapshot but was compiled with different flags
- // (namely --enable-asserts)
- final result2 = await runHelper(aotRuntime, [
- path.join(dir, 'main.dart.dill.so'),
- path.join(dir, 'spawnee_checked.dart.dill.so'),
- ]);
- Expect.notEquals(0, result2.exitCode);
- Expect.contains('Snapshot not compatible with the current VM configuration',
- result2.stderr);
+ if (!isProductMode) {
+ // File exists and is AOT snapshot but was compiled with different flags
+ // (namely --enable-asserts)
+ final result2 = await runHelper(aotRuntime, [
+ path.join(dir, 'main.dart.dill.so'),
+ path.join(dir, 'spawnee_checked.dart.dill.so'),
+ ]);
+ Expect.notEquals(0, result2.exitCode);
+ Expect.contains(
+ 'Snapshot not compatible with the current VM configuration',
+ result2.stderr);
+ }
- // File exists and is AOT snapshot but was compiled with different flags
- // (namely --enable-asserts)
+ // File does not exist.
final result3 = await runHelper(aotRuntime, [
path.join(dir, 'main.dart.dill.so'),
path.join(dir, 'does_not_exist.dart.dill.so'),
diff --git a/runtime/vm/compiler/assembler/assembler_riscv.cc b/runtime/vm/compiler/assembler/assembler_riscv.cc
index 5d739a0..897c9d7 100644
--- a/runtime/vm/compiler/assembler/assembler_riscv.cc
+++ b/runtime/vm/compiler/assembler/assembler_riscv.cc
@@ -4166,6 +4166,10 @@
LoadImmediate(dst, target::ToRawSmi(object));
}
+static const RegisterSet kRuntimeCallSavedRegisters(
+ kAbiVolatileCpuRegs | (1 << CALLEE_SAVED_TEMP) | (1 << CALLEE_SAVED_TEMP2),
+ kAbiVolatileFpuRegs);
+
// Note: leaf call sequence uses some abi callee save registers as scratch
// so they should be manually preserved.
void Assembler::EnterCallRuntimeFrame(intptr_t frame_size, bool is_leaf) {
@@ -4186,9 +4190,7 @@
addi(FP, SP, 2 * target::kWordSize + frame_size);
}
- const RegisterSet kVolatileRegisterSet(kAbiVolatileCpuRegs,
- kAbiVolatileFpuRegs);
- PushRegisters(kVolatileRegisterSet);
+ PushRegisters(kRuntimeCallSavedRegisters);
if (!is_leaf) { // Leaf calling sequence aligns the stack itself.
ReserveAlignedFrameSpace(0);
@@ -4196,18 +4198,15 @@
}
void Assembler::LeaveCallRuntimeFrame(bool is_leaf) {
- const RegisterSet kVolatileRegisterSet(kAbiVolatileCpuRegs,
- kAbiVolatileFpuRegs);
-
const intptr_t kPushedRegistersSize =
- kVolatileRegisterSet.CpuRegisterCount() * target::kWordSize +
- kVolatileRegisterSet.FpuRegisterCount() * kFpuRegisterSize +
+ kRuntimeCallSavedRegisters.CpuRegisterCount() * target::kWordSize +
+ kRuntimeCallSavedRegisters.FpuRegisterCount() * kFpuRegisterSize +
(target::frame_layout.dart_fixed_frame_size - 2) *
target::kWordSize; // From EnterStubFrame (excluding PC / FP)
subi(SP, FP, kPushedRegistersSize);
- PopRegisters(kVolatileRegisterSet);
+ PopRegisters(kRuntimeCallSavedRegisters);
LeaveStubFrame();
}
diff --git a/runtime/vm/compiler/backend/il_riscv.cc b/runtime/vm/compiler/backend/il_riscv.cc
index 1442eed..c9067af 100644
--- a/runtime/vm/compiler/backend/il_riscv.cc
+++ b/runtime/vm/compiler/backend/il_riscv.cc
@@ -4910,17 +4910,10 @@
} else {
UNIMPLEMENTED();
}
- // PP is a C volatile register.
- // SP will be aligned to the C stack alignment.
- __ mv(CALLEE_SAVED_TEMP, PP);
- __ mv(CALLEE_SAVED_TEMP2, SP);
// Call the function.
ASSERT(TargetFunction().is_leaf()); // No deopt info needed.
__ CallRuntime(TargetFunction(), TargetFunction().argument_count());
-
- __ mv(PP, CALLEE_SAVED_TEMP);
- __ mv(SP, CALLEE_SAVED_TEMP2);
}
LocationSummary* MathMinMaxInstr::MakeLocationSummary(Zone* zone,
@@ -5242,17 +5235,9 @@
UNIMPLEMENTED();
}
- // PP is a C volatile register.
- // SP will be aligned to the C stack alignment.
- __ mv(CALLEE_SAVED_TEMP, PP);
- __ mv(CALLEE_SAVED_TEMP2, SP);
-
ASSERT(TargetFunction().is_leaf()); // No deopt info needed.
__ CallRuntime(TargetFunction(), InputCount());
- __ mv(PP, CALLEE_SAVED_TEMP);
- __ mv(SP, CALLEE_SAVED_TEMP2);
-
// TODO(riscv): Special case pow?
}
diff --git a/runtime/vm/runtime_entry_riscv.cc b/runtime/vm/runtime_entry_riscv.cc
index 8dfab67..3987176 100644
--- a/runtime/vm/runtime_entry_riscv.cc
+++ b/runtime/vm/runtime_entry_riscv.cc
@@ -50,10 +50,11 @@
intptr_t argument_count) {
if (runtime_entry->is_leaf()) {
ASSERT(argument_count == runtime_entry->argument_count());
- // Caller is responsible for either using CallRuntimeScore or manually
- // saving PP (C volatile register) and SP (altered by alignment).
COMPILE_ASSERT(!IsAbiPreservedRegister(PP));
-
+ // PP is a C volatile register.
+ // SP will be aligned to the C stack alignment.
+ __ mv(CALLEE_SAVED_TEMP, PP);
+ __ mv(CALLEE_SAVED_TEMP2, SP);
__ lx(TMP2,
compiler::Address(THR, Thread::OffsetFromThread(runtime_entry)));
__ sx(TMP2, compiler::Address(THR, Thread::vm_tag_offset()));
@@ -61,6 +62,8 @@
__ jalr(TMP2);
__ LoadImmediate(TMP2, VMTag::kDartTagId);
__ sx(TMP2, compiler::Address(THR, Thread::vm_tag_offset()));
+ __ mv(PP, CALLEE_SAVED_TEMP);
+ __ mv(SP, CALLEE_SAVED_TEMP2);
// These registers must be preserved by runtime functions, otherwise
// we'd need to restore them here.
COMPILE_ASSERT(IsCalleeSavedRegister(THR));
diff --git a/sdk/lib/_internal/js_runtime/lib/async_patch.dart b/sdk/lib/_internal/js_runtime/lib/async_patch.dart
index 4888baf..5f8f5af 100644
--- a/sdk/lib/_internal/js_runtime/lib/async_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/async_patch.dart
@@ -481,7 +481,7 @@
add(event) => controller.add(event);
- addStream(Stream<T> stream) {
+ Future addStream(Stream<T> stream) {
return controller.addStream(stream, cancelOnError: false);
}
diff --git a/sdk/lib/_internal/js_runtime/lib/js_number.dart b/sdk/lib/_internal/js_runtime/lib/js_number.dart
index 678a61b..f217b53 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_number.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_number.dart
@@ -242,7 +242,7 @@
static String _handleIEtoString(String result) {
// Result is probably IE's untraditional format for large numbers,
// e.g., "8.0000000000008(e+15)" for 0x8000000000000800.toString(16).
- var match = JS('JSArray|Null',
+ List? match = JS('JSArray|Null',
r'/^([\da-z]+)(?:\.([\da-z]+))?\(e\+(\d+)\)$/.exec(#)', result);
if (match == null) {
// Then we don't know how to handle it at all.
diff --git a/tests/standalone/standalone_precompiled.status b/tests/standalone/standalone_precompiled.status
index 536731b..69da5e9 100644
--- a/tests/standalone/standalone_precompiled.status
+++ b/tests/standalone/standalone_precompiled.status
@@ -15,6 +15,7 @@
io/file_lock_test: Skip
io/file_read_special_device_test: Skip
io/http_client_stays_alive_test: Skip
+io/http_redirect_test: SkipByDesign # Requires dart:mirrors
io/http_response_deadline_test: Skip
io/http_server_close_response_after_error_test: Skip
io/https_unauthorized_test: Skip
diff --git a/tests/standalone_2/standalone_2_precompiled.status b/tests/standalone_2/standalone_2_precompiled.status
index 07c20e7..f7f7eb2 100644
--- a/tests/standalone_2/standalone_2_precompiled.status
+++ b/tests/standalone_2/standalone_2_precompiled.status
@@ -12,6 +12,7 @@
io/file_lock_test: Skip
io/file_read_special_device_test: Skip
io/http_client_stays_alive_test: Skip
+io/http_redirect_test: SkipByDesign # Requires dart:mirrors
io/http_response_deadline_test: Skip
io/http_server_close_response_after_error_test: Skip
io/https_unauthorized_test: Skip
diff --git a/tests/web/48383_test.dart b/tests/web/48383_test.dart
new file mode 100644
index 0000000..3100f74
--- /dev/null
+++ b/tests/web/48383_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+
+void main() {
+ load();
+ load(cond: true);
+ Expect.equals('side-effect', state);
+}
+
+String state = 'start';
+
+// `cond` can be both true and false.
+// `use` is always be false.
+dynamic load({bool cond = false, bool use = false}) {
+ int? data;
+ if (cond) {
+ data = callWithSideEffects();
+ }
+ return [if (use && cond) data];
+}
+
+@pragma('dart2js:noInline')
+int callWithSideEffects() {
+ state = 'side-effect';
+ return 2;
+}
diff --git a/tests/web_2/48383_test.dart b/tests/web_2/48383_test.dart
new file mode 100644
index 0000000..3100f74
--- /dev/null
+++ b/tests/web_2/48383_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+
+void main() {
+ load();
+ load(cond: true);
+ Expect.equals('side-effect', state);
+}
+
+String state = 'start';
+
+// `cond` can be both true and false.
+// `use` is always be false.
+dynamic load({bool cond = false, bool use = false}) {
+ int? data;
+ if (cond) {
+ data = callWithSideEffects();
+ }
+ return [if (use && cond) data];
+}
+
+@pragma('dart2js:noInline')
+int callWithSideEffects() {
+ state = 'side-effect';
+ return 2;
+}
diff --git a/tools/VERSION b/tools/VERSION
index f17707f..eeb0ced 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 17
PATCH 0
-PRERELEASE 107
+PRERELEASE 108
PRERELEASE_PATCH 0
\ No newline at end of file