| Index: pkg/compiler/lib/src/ssa/builder_kernel.dart
|
| diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart
|
| index 597d6fa9a55ef78c336b36dad2bf14199f7a9a31..60fda9d01b2ad6d19493b83e39f353a42f8f884e 100644
|
| --- a/pkg/compiler/lib/src/ssa/builder_kernel.dart
|
| +++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
|
| @@ -32,7 +32,7 @@ import '../tree/nodes.dart' show Node;
|
| import '../types/masks.dart';
|
| import '../universe/selector.dart';
|
| import '../universe/side_effects.dart' show SideEffects;
|
| -import '../universe/use.dart' show DynamicUse;
|
| +import '../universe/use.dart' show ConstantUse, DynamicUse;
|
| import '../universe/world_builder.dart' show CodegenWorldBuilder;
|
| import '../world.dart';
|
| import 'graph_builder.dart';
|
| @@ -145,6 +145,7 @@ class KernelSsaGraphBuilder extends ir.Visitor
|
| }
|
| buildField(target);
|
| } else if (target is ir.Constructor) {
|
| + _targetFunction = (target as ir.Constructor).function;
|
| if (targetElement is ConstructorBodyEntity) {
|
| buildConstructorBody(target);
|
| } else {
|
| @@ -161,10 +162,43 @@ class KernelSsaGraphBuilder extends ir.Visitor
|
| '$target for $targetElement';
|
| }
|
| assert(graph.isValid());
|
| + if (_targetFunction != null) {
|
| + _ensureDefaultArgumentValues(_targetFunction);
|
| + }
|
| return graph;
|
| });
|
| }
|
|
|
| + void _ensureDefaultArgumentValues(ir.FunctionNode function) {
|
| + // Register all [function]'s default argument values.
|
| + //
|
| + // Default values might be (or contain) functions that are not referenced
|
| + // from anywhere else so we need to ensure these are enqueued. Stubs and
|
| + // `Function.apply` data are created after the codegen queue is closed, so
|
| + // we force these functions into the queue by registering the constants as
|
| + // used in advance. See language/cyclic_default_values_test.dart for an
|
| + // example.
|
| + //
|
| + // TODO(sra): We could be more precise if stubs and `Function.apply` data
|
| + // were generated by the codegen enqueuer. In practice even in huge programs
|
| + // there are only very small number of constants created here that are not
|
| + // actually used.
|
| + void registerDefaultValue(ir.VariableDeclaration node) {
|
| + ConstantValue constantValue =
|
| + _elementMap.getConstantValue(node.initializer, implicitNull: true);
|
| + assert(
|
| + constantValue != null,
|
| + failedAt(_elementMap.getMethod(function.parent),
|
| + 'No constant computed for $node'));
|
| + registry?.registerConstantUse(new ConstantUse.init(constantValue));
|
| + }
|
| +
|
| + function.positionalParameters
|
| + .skip(function.requiredParameterCount)
|
| + .forEach(registerDefaultValue);
|
| + function.namedParameters.forEach(registerDefaultValue);
|
| + }
|
| +
|
| @override
|
| ConstantValue getFieldInitialConstantValue(FieldEntity field) {
|
| assert(field == targetElement);
|
|
|