Create codegen work item for all members
Ensures that constants of effectively constant instance fields are
registered also with --omit-implicit-checks.
Change-Id: Icc31799f1cc5f565321c832780f30c711e9c8c50
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/96160
Reviewed-by: Sigmund Cherem <sigmund@google.com>
Commit-Queue: Sigmund Cherem <sigmund@google.com>
diff --git a/pkg/compiler/lib/src/js_model/js_strategy.dart b/pkg/compiler/lib/src/js_model/js_strategy.dart
index e605804..3f13c78 100644
--- a/pkg/compiler/lib/src/js_model/js_strategy.dart
+++ b/pkg/compiler/lib/src/js_model/js_strategy.dart
@@ -26,7 +26,6 @@
import '../js_backend/native_data.dart';
import '../kernel/kernel_strategy.dart';
import '../native/behavior.dart';
-import '../options.dart';
import '../ssa/builder_kernel.dart';
import '../ssa/nodes.dart';
import '../ssa/ssa.dart';
@@ -138,21 +137,9 @@
KernelCodegenWorkItemBuilder(
this._backend, this._closedWorld, this._globalInferenceResults);
- CompilerOptions get _options => _backend.compiler.options;
-
@override
CodegenWorkItem createWorkItem(MemberEntity entity) {
if (entity.isAbstract) return null;
-
- // Codegen inlines field initializers. It only needs to generate
- // code for checked setters.
- if (entity.isField && entity.isInstanceMember) {
- if (!_options.parameterCheckPolicy.isEmitted ||
- entity.enclosingClass.isClosure) {
- return null;
- }
- }
-
return new KernelCodegenWorkItem(
_backend, _closedWorld, _globalInferenceResults, entity);
}
diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart
index e1fe0fb..bbb9618 100644
--- a/pkg/compiler/lib/src/ssa/builder_kernel.dart
+++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
@@ -238,6 +238,15 @@
// eager and non-final fields.
backend.constants.registerLazyStatic(targetElement);
}
+ } else {
+ assert(targetElement.isInstanceMember);
+ if (_fieldAnalysis
+ .getFieldData(targetElement)
+ .isEffectivelyFinal ||
+ !options.parameterCheckPolicy.isEmitted) {
+ // No need for a checked setter.
+ return null;
+ }
}
buildField(target);
} else if (target is ir.FunctionExpression) {
@@ -262,8 +271,8 @@
buildConstructorBody(constructor);
break;
case MemberKind.closureField:
- failedAt(targetElement, "Unexpected closure field: $targetElement");
- break;
+ // Closure fields have no setter and therefore never require any code.
+ return null;
case MemberKind.signature:
ir.Node target = definition.node;
ir.FunctionNode originalClosureNode;
diff --git a/tests/compiler/dart2js_extra/effectively_constant_instance_field_test.dart b/tests/compiler/dart2js_extra/effectively_constant_instance_field_test.dart
new file mode 100644
index 0000000..94020a2
--- /dev/null
+++ b/tests/compiler/dart2js_extra/effectively_constant_instance_field_test.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2019, 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.
+
+// dart2jsOptions=--omit-implicit-checks
+
+import 'package:expect/expect.dart';
+
+class C {
+ const C();
+}
+
+class A {
+ var field = const C();
+}
+
+class B {
+ var field;
+}
+
+@pragma('dart2js:noInline')
+test(o) => o.field;
+
+main() {
+ Expect.isNotNull(test(new A()));
+ Expect.isNull(test(new B()));
+}