Skip to content

Commit

Permalink
Wrap field initializers copied by TFA in a FileUriExpression.
Browse files Browse the repository at this point in the history
Before TFA runs, MixinFullResolution will clone a mixin's fields into the application classes for that mixin. The cloned Field on the application class will have a fileUri that refers to the original mixin file.

However, TFA then copies those fields into FieldInitializers which don't have a fileUri context and so the fileUri for the surrounding Constructor is used. This leaves expressions in the initializer with offsets relative to the mixin's file but in the context of the mixin application's file.

To fix this, we can wrap the initializer in a FileUriExpression referring to the original mixin class. We only do this if the field the initializer is copied from refers to a different file than the target constructor.

Also add handlers for FileUriExpressions to several visitors that don't already support this new AST node.

Change-Id: I47b0d48dfe87303949130a40216b199949cfa1d9
Tested: Existing test suite.
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/360420
Commit-Queue: Nate Biggs <[email protected]>
Reviewed-by: Ömer Ağacan <[email protected]>
Reviewed-by: Alexander Markov <[email protected]>
  • Loading branch information
natebiggs authored and Commit Queue committed Apr 2, 2024
1 parent f54eb08 commit 1e8ea8a
Show file tree
Hide file tree
Showing 7 changed files with 37 additions and 0 deletions.
5 changes: 5 additions & 0 deletions pkg/compiler/lib/src/inferrer/builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2246,6 +2246,11 @@ class KernelTypeGraphBuilder extends ir.VisitorDefault<TypeInformation?>
return TypeInformationConstantVisitor(this, node)
.visitConstant(node.constant);
}

@override
TypeInformation visitFileUriExpression(ir.FileUriExpression node) {
return visit(node.expression)!;
}
}

class TypeInformationConstantVisitor
Expand Down
5 changes: 5 additions & 0 deletions pkg/compiler/lib/src/ir/scope_visitor.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1443,6 +1443,11 @@ class ScopeModelBuilder extends ir.VisitorDefault<EvaluationComplexity>
return const EvaluationComplexity.constant();
}

@override
EvaluationComplexity visitFileUriExpression(ir.FileUriExpression node) {
return visitNode(node.expression);
}

/// Returns true if the node is a field, or a constructor (factory or
/// generative).
bool _isFieldOrConstructor(ir.Node node) =>
Expand Down
5 changes: 5 additions & 0 deletions pkg/compiler/lib/src/ssa/builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6228,6 +6228,11 @@ class KernelSsaGraphBuilder extends ir.VisitorDefault<void>
..cleanUp();
}

@override
void visitFileUriExpression(ir.FileUriExpression node) {
node.expression.accept(this);
}

bool _tryInlineMethod(
FunctionEntity function,
Selector? selector,
Expand Down
3 changes: 3 additions & 0 deletions pkg/dart2wasm/lib/await_transformer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -767,6 +767,9 @@ class _ExpressionTransformer extends Transformer {
@override
TreeNode visitRethrow(Rethrow expr) => nullary(expr);

@override
TreeNode visitFileUriExpression(FileUriExpression expr) => unary(expr);

@override
TreeNode visitVariableGet(VariableGet expr) {
Expression result = expr;
Expand Down
6 changes: 6 additions & 0 deletions pkg/dart2wasm/lib/code_generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3160,6 +3160,12 @@ class CodeGenerator extends ExpressionVisitor1<w.ValueType, w.ValueType>
return translator.topInfo.nullableType;
}

@override
w.ValueType visitFileUriExpression(
FileUriExpression node, w.ValueType expectedType) {
return wrap(node.expression, expectedType);
}

// Generates a function for a constructor's body, where the allocated struct
// object is passed to this function.
void generateConstructorBody(Reference target) {
Expand Down
5 changes: 5 additions & 0 deletions pkg/vm/lib/transformations/type_flow/summary_collector.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2635,6 +2635,11 @@ class SummaryCollector extends RecursiveResultVisitor<TypeExpr?> {
_visit(node.operand);
return _staticType(node);
}

@override
TypeExpr visitFileUriExpression(FileUriExpression node) {
return _visit(node.expression);
}
}

class RuntimeTypeTranslatorImpl
Expand Down
8 changes: 8 additions & 0 deletions pkg/vm/lib/transformations/type_flow/transformer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,14 @@ class MoveFieldInitializers {
if (!isFirst) {
initExpr = CloneVisitorNotMembers().clone(initExpr);
}
if (c.fileUri != f.fileUri) {
if (initExpr is ConstantExpression) {
initExpr = FileUriConstantExpression(initExpr.constant,
type: initExpr.type, fileUri: f.fileUri);
} else {
initExpr = FileUriExpression(initExpr, f.fileUri);
}
}
final Initializer newInit = initializedFields.contains(f)
? LocalInitializer(VariableDeclaration(null,
initializer: initExpr, isSynthesized: true))
Expand Down

0 comments on commit 1e8ea8a

Please sign in to comment.