Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(587)

Unified Diff: pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart

Issue 1200823002: dart2cps: Fix bug in constructors. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Revert+Unrevert+Rebase Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | pkg/pkg.status » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
index aebd19dbd5fa85b098d1f1d28049b93dde0091cc..13f4306d5b4951b1d675f368dc074f05beb5ac5d 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
@@ -2123,10 +2123,6 @@ class JsIrBuilderVisitor extends IrBuilderVisitor {
/// It is computed by the [ClosureTranslator].
ClosureClassMap closureClassMap;
- /// During construction of a constructor factory, [fieldValues] maps fields
- /// to the primitive containing their initial value.
- Map<FieldElement, ir.Primitive> fieldValues = <FieldElement, ir.Primitive>{};
-
JsIrBuilderVisitor(TreeElements elements,
Compiler compiler,
SourceInformationBuilder sourceInformationBuilder)
@@ -2269,15 +2265,23 @@ class JsIrBuilderVisitor extends IrBuilderVisitor {
});
}
+ /// Make a visitor suitable for translating ASTs taken from [context].
+ ///
+ /// Every visitor can only be applied to nodes in one context, because
+ /// the [elements] field is specific to that context.
+ JsIrBuilderVisitor makeVisitorForContext(AstElement context) {
+ return new JsIrBuilderVisitor(
+ context.resolvedAst.elements,
+ compiler,
+ sourceInformationBuilder.forContext(context));
+ }
+
/// Builds the IR for an [expression] taken from a different [context].
///
/// Such expressions need to be compiled with a different [sourceFile] and
/// [elements] mapping.
ir.Primitive inlineExpression(AstElement context, ast.Expression expression) {
- JsIrBuilderVisitor visitor = new JsIrBuilderVisitor(
- context.resolvedAst.elements,
- compiler,
- sourceInformationBuilder.forContext(context));
+ JsIrBuilderVisitor visitor = makeVisitorForContext(context);
return visitor.withBuilder(irBuilder, () => visitor.visit(expression));
}
@@ -2286,10 +2290,7 @@ class JsIrBuilderVisitor extends IrBuilderVisitor {
/// Such constants need to be compiled with a different [sourceFile] and
/// [elements] mapping.
ir.Primitive inlineConstant(AstElement context, ast.Expression exp) {
- JsIrBuilderVisitor visitor = new JsIrBuilderVisitor(
- context.resolvedAst.elements,
- compiler,
- sourceInformationBuilder.forContext(context));
+ JsIrBuilderVisitor visitor = makeVisitorForContext(context);
return visitor.withBuilder(irBuilder, () => visitor.translateConstant(exp));
}
@@ -2358,11 +2359,16 @@ class JsIrBuilderVisitor extends IrBuilderVisitor {
// get it out of the way here to avoid complications with mixins.
loadTypeVariablesForSuperClasses(classElement);
+ /// Maps each field from this class or a superclass to its initial value.
+ Map<FieldElement, ir.Primitive> fieldValues =
+ <FieldElement, ir.Primitive>{};
+
// -- Evaluate field initializers ---
// Evaluate field initializers in constructor and super constructors.
irBuilder.enterInitializers();
List<ConstructorElement> constructorList = <ConstructorElement>[];
- evaluateConstructorFieldInitializers(constructor, constructorList);
+ evaluateConstructorFieldInitializers(
+ constructor, constructorList, fieldValues);
irBuilder.leaveInitializers();
// All parameters in all constructors are now bound in the environment.
@@ -2418,8 +2424,12 @@ class JsIrBuilderVisitor extends IrBuilderVisitor {
/// the environment, but will be put there by this procedure.
///
/// All constructors will be added to [supers], with superconstructors first.
- void evaluateConstructorFieldInitializers(ConstructorElement constructor,
- List<ConstructorElement> supers) {
+ void evaluateConstructorFieldInitializers(
+ ConstructorElement constructor,
+ List<ConstructorElement> supers,
+ Map<FieldElement, ir.Primitive> fieldValues) {
+ assert(constructor.isImplementation);
+ assert(constructor == elements.analyzedElement);
ClassElement enclosingClass = constructor.enclosingClass.implementation;
// Evaluate declaration-site field initializers, unless this constructor
// redirects to another using a `this()` initializer. In that case, these
@@ -2456,19 +2466,18 @@ class JsIrBuilderVisitor extends IrBuilderVisitor {
if (initializer is ast.SendSet) {
// Field initializer.
FieldElement field = elements[initializer];
- fieldValues[field] =
- inlineExpression(constructor, initializer.arguments.head);
+ fieldValues[field] = visit(initializer.arguments.head);
} else if (initializer is ast.Send) {
// Super or this initializer.
ConstructorElement target = elements[initializer].implementation;
Selector selector = elements.getSelector(initializer);
- ir.Primitive evaluateArgument(ast.Node arg) {
- return inlineExpression(constructor, arg);
- }
- List<ir.Primitive> arguments =
- initializer.arguments.mapToList(evaluateArgument);
- loadArguments(target, selector, arguments);
- evaluateConstructorFieldInitializers(target, supers);
+ List<ir.Primitive> arguments = initializer.arguments.mapToList(visit);
+ evaluateConstructorCallFromInitializer(
+ target,
+ selector.callStructure,
+ arguments,
+ supers,
+ fieldValues);
hasConstructorCall = true;
} else {
compiler.internalError(initializer,
@@ -2483,12 +2492,35 @@ class JsIrBuilderVisitor extends IrBuilderVisitor {
if (target == null) {
compiler.internalError(superClass, "No default constructor available.");
}
- evaluateConstructorFieldInitializers(target, supers);
+ target = target.implementation;
+ evaluateConstructorCallFromInitializer(
+ target,
+ CallStructure.NO_ARGS,
+ const [],
+ supers,
+ fieldValues);
}
// Add this constructor after the superconstructors.
supers.add(constructor);
}
+ /// Evaluates a call to the given constructor from an initializer list.
+ ///
+ /// Calls [loadArguments] and [evaluateConstructorFieldInitializers] in a
+ /// visitor that has the proper [TreeElements] mapping.
+ void evaluateConstructorCallFromInitializer(
+ ConstructorElement target,
+ CallStructure call,
+ List<ir.Primitive> arguments,
+ List<ConstructorElement> supers,
+ Map<FieldElement, ir.Primitive> fieldValues) {
+ JsIrBuilderVisitor visitor = makeVisitorForContext(target);
+ return visitor.withBuilder(irBuilder, () {
+ visitor.loadArguments(target, call, arguments);
+ visitor.evaluateConstructorFieldInitializers(target, supers, fieldValues);
+ });
+ }
+
/// Loads the type variables for all super classes of [superClass] into the
/// IR builder's environment with their corresponding values.
///
@@ -2527,9 +2559,10 @@ class JsIrBuilderVisitor extends IrBuilderVisitor {
/// Defaults for optional arguments are evaluated in order to ensure
/// all parameters are available in the environment.
void loadArguments(ConstructorElement target,
- Selector selector,
+ CallStructure call,
List<ir.Primitive> arguments) {
- target = target.implementation;
+ assert(target.isImplementation);
+ assert(target == elements.analyzedElement);
FunctionSignature signature = target.functionSignature;
// Establish a scope in case parameters are captured.
@@ -2548,9 +2581,9 @@ class JsIrBuilderVisitor extends IrBuilderVisitor {
ir.Primitive value;
// Load argument if provided.
if (signature.optionalParametersAreNamed) {
- int nameIndex = selector.namedArguments.indexOf(param.name);
+ int nameIndex = call.namedArguments.indexOf(param.name);
if (nameIndex != -1) {
- int translatedIndex = selector.positionalArgumentCount + nameIndex;
+ int translatedIndex = call.positionalArgumentCount + nameIndex;
value = arguments[translatedIndex];
}
} else if (index < arguments.length) {
@@ -2559,7 +2592,7 @@ class JsIrBuilderVisitor extends IrBuilderVisitor {
// Load default if argument was not provided.
if (value == null) {
if (param.initializer != null) {
- value = inlineExpression(target, param.initializer);
+ value = visit(param.initializer);
} else {
value = irBuilder.buildNullConstant();
}
@@ -2581,9 +2614,8 @@ class JsIrBuilderVisitor extends IrBuilderVisitor {
// cannot add a BoxLocal as parameter, because BoxLocal is not an element.
// Instead of forging ParameterElements to forge a FunctionSignature, we
// need a way to create backend methods without creating more fake elements.
-
assert(constructor.isGenerativeConstructor);
- assert(invariant(constructor, constructor.isImplementation));
+ assert(constructor.isImplementation);
if (constructor.isSynthesized) return null;
ast.FunctionExpression node = constructor.node;
// If we know the body doesn't have any code, we don't generate it.
« no previous file with comments | « no previous file | pkg/pkg.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698