Index: pkg/compiler/lib/src/ssa/builder.dart |
diff --git a/pkg/compiler/lib/src/ssa/builder.dart b/pkg/compiler/lib/src/ssa/builder.dart |
index 077b587c759f9e8c51f83b0c3dc0184468b6447b..39fd93bc7310142405631beae1aa0e9309b933e2 100644 |
--- a/pkg/compiler/lib/src/ssa/builder.dart |
+++ b/pkg/compiler/lib/src/ssa/builder.dart |
@@ -55,29 +55,60 @@ import 'type_builder.dart'; |
import 'types.dart'; |
abstract class SsaAstBuilderBase extends CompilerTask |
- with SsaBuilderFieldMixin |
implements SsaBuilderTask { |
final JavaScriptBackend backend; |
SsaAstBuilderBase(this.backend) : super(backend.compiler.measurer); |
- ConstantValue getFieldInitialConstantValue(FieldElement field) { |
- ConstantExpression constant = field.constant; |
- if (constant != null) { |
- ConstantValue initialValue = backend.constants.getConstantValue(constant); |
- if (initialValue == null) { |
- assert( |
- field.isInstanceMember || |
- constant.isImplicit || |
- constant.isPotential, |
- failedAt( |
- field, |
- "Constant expression without value: " |
- "${constant.toStructuredText()}.")); |
+ /// Handle field initializer of `work.element`. Returns `true` if no code |
+ /// is needed for the field. |
+ /// |
+ /// If `work.element` is a field with a constant initializer, the value is |
+ /// registered with the world impact. Otherwise the cyclic-throw helper is |
+ /// registered for the lazy value computation. |
+ /// |
+ /// If the field is constant, no code is needed for the field and the method |
+ /// return `true`. |
+ bool handleConstantField( |
+ ElementCodegenWorkItem work, ClosedWorld closedWorld) { |
+ MemberElement element = work.element; |
+ if (element.isField) { |
+ FieldElement field = element; |
+ ConstantExpression constant = field.constant; |
+ if (constant != null) { |
+ ConstantValue initialValue = |
+ backend.constants.getConstantValue(constant); |
+ if (initialValue != null) { |
+ work.registry.worldImpact |
+ .registerConstantUse(new ConstantUse.init(initialValue)); |
+ // We don't need to generate code for static or top-level |
+ // variables. For instance variables, we may need to generate |
+ // the checked setter. |
+ if (field.isStatic || field.isTopLevel) { |
+ /// No code is created for this field. |
+ return true; |
+ } |
+ } else { |
+ assert( |
+ field.isInstanceMember || |
+ constant.isImplicit || |
+ constant.isPotential, |
+ failedAt( |
+ field, |
+ "Constant expression without value: " |
+ "${constant.toStructuredText()}.")); |
+ } |
+ } else { |
+ // If the constant-handler was not able to produce a result we have to |
+ // go through the builder (below) to generate the lazy initializer for |
+ // the static variable. |
+ // We also need to register the use of the cyclic-error helper. |
+ work.registry.worldImpact.registerStaticUse(new StaticUse.staticInvoke( |
+ closedWorld.commonElements.cyclicThrowHelper, |
+ CallStructure.ONE_ARG)); |
} |
- return initialValue; |
} |
- return null; |
+ return false; |
} |
} |
@@ -95,7 +126,7 @@ class SsaAstBuilderTask extends SsaAstBuilderBase { |
HGraph build(ElementCodegenWorkItem work, ClosedWorld closedWorld) { |
return measure(() { |
- if (handleConstantField(work.element, work.registry, closedWorld)) { |
+ if (handleConstantField(work, closedWorld)) { |
// No code is generated for `work.element`. |
return null; |
} |