[dart2js] Disentangle instance field setter and static field initializer

A FieldEntity is used as the entity for generating the setter of an
instance field (when a check is required), and as the entity for the
initializer expression for a static or top-level field.

I think it is a bit clearer to have a separate method for each case
rather than one method with conditional paths.

Change-Id: I32e63c3f3566a63e3d38315cab17d613f006405e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/253562
Commit-Queue: Stephen Adams <sra@google.com>
Reviewed-by: Mayank Patke <fishythefish@google.com>
This commit is contained in:
Stephen Adams 2022-08-03 17:06:28 +00:00 committed by Commit Bot
parent e7df4c9b19
commit 5e267854e1

View file

@ -478,7 +478,11 @@ class KernelSsaGraphBuilder extends ir.Visitor<void> with ir.VisitorVoidMixin {
return null; return null;
} }
} }
_buildField(target); if (targetElement.isInstanceMember) {
_buildInstanceFieldSetter(target);
} else {
_buildStaticFieldInitializer(target);
}
} else if (target is ir.LocalFunction) { } else if (target is ir.LocalFunction) {
_buildFunctionNode(targetElement, _buildFunctionNode(targetElement,
_ensureDefaultArgumentValues(null, target.function)); _ensureDefaultArgumentValues(null, target.function));
@ -579,52 +583,56 @@ class KernelSsaGraphBuilder extends ir.Visitor<void> with ir.VisitorVoidMixin {
return function; return function;
} }
void _buildField(ir.Field node) { void _buildInstanceFieldSetter(ir.Field node) {
graph.isLazyInitializer = node.isStatic; assert(!node.isStatic);
FieldEntity field = _elementMap.getMember(node); FieldEntity field = _elementMap.getMember(node);
_openFunction(field, checks: TargetChecks.none); _openFunction(field, checks: TargetChecks.none);
if (node.isInstanceMember && HInstruction thisInstruction = localsHandler.readThis(
closedWorld.annotationsData.getParameterCheckPolicy(field).isEmitted) { sourceInformation: _sourceInformationBuilder.buildGet(node));
HInstruction thisInstruction = localsHandler.readThis( // Use dynamic type because the type computed by the inferrer is
sourceInformation: _sourceInformationBuilder.buildGet(node)); // narrowed to the type annotation.
// Use dynamic type because the type computed by the inferrer is HInstruction parameter =
// narrowed to the type annotation. HParameterValue(field, _abstractValueDomain.dynamicType);
HInstruction parameter = // Add the parameter as the last instruction of the entry block.
HParameterValue(field, _abstractValueDomain.dynamicType); // If the method is intercepted, we want the actual receiver
// Add the parameter as the last instruction of the entry block. // to be the first parameter.
// If the method is intercepted, we want the actual receiver graph.entry.addBefore(graph.entry.last, parameter);
// to be the first parameter. DartType type = _getDartTypeIfValid(node.type);
graph.entry.addBefore(graph.entry.last, parameter); HInstruction value = _typeBuilder.potentiallyCheckOrTrustTypeOfParameter(
DartType type = _getDartTypeIfValid(node.type); field, parameter, type);
HInstruction value = _typeBuilder.potentiallyCheckOrTrustTypeOfParameter( // TODO(sra): Pass source information to
field, parameter, type); // [potentiallyCheckOrTrustTypeOfParameter].
// TODO(sra): Pass source information to // TODO(sra): The source information should indicate the field and
// [potentiallyCheckOrTrustTypeOfParameter]. // possibly its type but not the initializer.
// TODO(sra): The source information should indicate the field and value.sourceInformation ??= _sourceInformationBuilder.buildSet(node);
// possibly its type but not the initializer. value = _potentiallyAssertNotNull(field, node, value, type);
value.sourceInformation ??= _sourceInformationBuilder.buildSet(node); if (!_fieldAnalysis.getFieldData(field).isElided) {
value = _potentiallyAssertNotNull(field, node, value, type); add(HFieldSet(_abstractValueDomain, field, thisInstruction, value));
if (!_fieldAnalysis.getFieldData(field).isElided) {
add(HFieldSet(_abstractValueDomain, field, thisInstruction, value));
}
} else {
if (node.initializer != null) {
node.initializer.accept(this);
HInstruction fieldValue = pop();
HInstruction checkInstruction =
_typeBuilder.potentiallyCheckOrTrustTypeOfAssignment(
field, fieldValue, _getDartTypeIfValid(node.type));
stack.add(checkInstruction);
} else {
stack.add(graph.addConstantNull(closedWorld));
}
HInstruction value = pop();
_closeAndGotoExit(HReturn(_abstractValueDomain, value,
_sourceInformationBuilder.buildReturn(node)));
} }
_closeFunction(); _closeFunction();
} }
void _buildStaticFieldInitializer(ir.Field node) {
assert(node.isStatic);
graph.isLazyInitializer = true;
FieldEntity field = _elementMap.getMember(node);
_openFunction(field, checks: TargetChecks.none);
if (node.initializer != null) {
node.initializer.accept(this);
HInstruction fieldValue = pop();
HInstruction checkInstruction =
_typeBuilder.potentiallyCheckOrTrustTypeOfAssignment(
field, fieldValue, _getDartTypeIfValid(node.type));
stack.add(checkInstruction);
} else {
stack.add(graph.addConstantNull(closedWorld));
}
HInstruction value = pop();
_closeAndGotoExit(HReturn(_abstractValueDomain, value,
_sourceInformationBuilder.buildReturn(node)));
_closeFunction();
}
DartType _getDartTypeIfValid(ir.DartType type) { DartType _getDartTypeIfValid(ir.DartType type) {
if (type is ir.InvalidType) return dartTypes.dynamicType(); if (type is ir.InvalidType) return dartTypes.dynamicType();
return _elementMap.getDartType(type); return _elementMap.getDartType(type);