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

Unified Diff: frog/leg/ssa/builder.dart

Issue 9720030: Compile initializers in right order. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Update status files. Created 8 years, 9 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 | tests/co19/co19-leg.status » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: frog/leg/ssa/builder.dart
diff --git a/frog/leg/ssa/builder.dart b/frog/leg/ssa/builder.dart
index 94ba1d6474ef4f20048106f7dfe01ae329c9d36c..3d3ff072f4691b93ddc41a5a3be117f347c6d9c3 100644
--- a/frog/leg/ssa/builder.dart
+++ b/frog/leg/ssa/builder.dart
@@ -768,48 +768,80 @@ class SsaBuilder implements Visitor {
}
/**
- * Run through the initializers and inline all field initializers. Returns the
- * next constructor to analyze.
+ * Run through the initializers and inline all field initializers. Recursively
+ * inlines super initializers.
+ *
+ * The constructors of the inlined initializers is added to [constructors]
+ * with sub constructors having a lower index then super constructors.
ngeoffray 2012/03/18 14:00:44 then -> than
floitsch 2012/03/18 15:36:10 Done.
*/
- FunctionElement analyzeInitializers(Link<Node> initializers,
- Map<Element, HInstruction> fieldValues) {
- FunctionElement nextConstructor;
- for (Link<Node> link = initializers; !link.isEmpty(); link = link.tail) {
- assert(link.head is Send);
- if (link.head is !SendSet) {
- // A super initializer or constructor redirection.
- Send call = link.head;
- assert(Initializers.isSuperConstructorCall(call) ||
- Initializers.isConstructorRedirect(call));
- assert(nextConstructor === null);
- nextConstructor = elements[call];
- // Visit arguments and map the corresponding parameter value to
- // the resulting HInstruction value.
- List<HInstruction> arguments = new List<HInstruction>();
- addStaticSendArgumentsToList(call, nextConstructor, arguments);
- int index = 0;
- FunctionParameters parameters =
- nextConstructor.computeParameters(compiler);
- parameters.forEachParameter((Element parameter) {
- HInstruction argument = arguments[index++];
- localsHandler.updateLocal(parameter, argument);
- // Don't forget to update the field, if the parameter is of the
- // form [:this.x:].
- if (parameter.kind == ElementKind.FIELD_PARAMETER) {
- FieldParameterElement fieldParameterElement = parameter;
- fieldValues[fieldParameterElement.fieldElement] = argument;
- }
- });
- } else {
- // A field initializer.
- SendSet init = link.head;
- Link<Node> arguments = init.arguments;
- assert(!arguments.isEmpty() && arguments.tail.isEmpty());
- visit(arguments.head);
- fieldValues[elements[init]] = pop();
+ void inlineInitializers(FunctionElement constructor,
+ List<FunctionElement> constructors,
+ Map<Element, HInstruction> fieldValues) {
+ TreeElements oldElements = elements;
+ constructors.addLast(constructor);
+ bool initializedSuper = false;
+ elements = compiler.resolver.resolveMethodElement(constructor);
+ FunctionExpression functionNode = constructor.parseNode(compiler);
+
+ if (functionNode.initializers !== null) {
+ Link<Node> initializers = functionNode.initializers.nodes;
+ for (Link<Node> link = initializers; !link.isEmpty(); link = link.tail) {
+ assert(link.head is Send);
+ if (link.head is !SendSet) {
+ // A super initializer or constructor redirection.
+ Send call = link.head;
+ assert(Initializers.isSuperConstructorCall(call) ||
+ Initializers.isConstructorRedirect(call));
+ FunctionElement nextConstructor = elements[call];
+ // Visit arguments and map the corresponding parameter value to
+ // the resulting HInstruction value.
+ List<HInstruction> arguments = new List<HInstruction>();
+ addStaticSendArgumentsToList(call, nextConstructor, arguments);
+ int index = 0;
+ FunctionParameters parameters =
+ nextConstructor.computeParameters(compiler);
+ parameters.forEachParameter((Element parameter) {
+ HInstruction argument = arguments[index++];
+ localsHandler.updateLocal(parameter, argument);
+ // Don't forget to update the field, if the parameter is of the
+ // form [:this.x:].
+ if (parameter.kind == ElementKind.FIELD_PARAMETER) {
+ FieldParameterElement fieldParameterElement = parameter;
+ fieldValues[fieldParameterElement.fieldElement] = argument;
+ }
+ });
+ inlineInitializers(nextConstructor, constructors, fieldValues);
+ initializedSuper = true;
+ } else {
+ // A field initializer.
+ SendSet init = link.head;
+ Link<Node> arguments = init.arguments;
+ assert(!arguments.isEmpty() && arguments.tail.isEmpty());
+ visit(arguments.head);
+ fieldValues[elements[init]] = pop();
+ }
}
}
- return nextConstructor;
+
+ if (!initializedSuper) {
+ // No super initializer found. Try to find the default constructor if
ngeoffray 2012/03/18 14:00:44 default -> super
floitsch 2012/03/18 15:36:10 I think 'default' is correct here. We are trying t
ngeoffray 2012/03/18 15:44:53 Right. 'default' bothers me because it makes me th
+ // the class is not Object.
+ ClassElement enclosingClass = constructor.enclosingElement;
+ ClassElement superClass = enclosingClass.superclass;
+ ClassElement objectElement = compiler.coreLibrary.find(Types.OBJECT);
ngeoffray 2012/03/18 14:00:44 compiler.objectClass
floitsch 2012/03/18 15:36:10 Done.
+ if (enclosingClass != objectElement) {
+ assert(superClass !== null);
+ assert(superClass.isResolved);
+ FunctionElement nextConstructor =
+ superClass.lookupConstructor(superClass.name);
+ if (nextConstructor === null) {
+ compiler.internalError("no default constructor available");
ngeoffray 2012/03/18 14:00:44 default -> super
floitsch 2012/03/18 15:36:10 ditto.
+ }
+ inlineInitializers(nextConstructor, constructors, fieldValues);
+ }
+ }
+
+ elements = oldElements;
}
/**
@@ -849,34 +881,8 @@ class SsaBuilder implements Visitor {
// Analyze the constructor and all referenced constructors and collect
// initializers and constructor bodies.
- FunctionElement nextConstructor = functionElement;
- while (nextConstructor != null) {
- FunctionElement constructor = nextConstructor;
- constructors.addLast(constructor);
- nextConstructor = null;
- elements = compiler.resolver.resolveMethodElement(constructor);
- FunctionExpression functionNode = constructor.parseNode(compiler);
- Link<Node> initializers = const EmptyLink<Node>();
- if (functionNode.initializers !== null) {
- nextConstructor =
- analyzeInitializers(functionNode.initializers.nodes, fieldValues);
- }
- if (nextConstructor === null) {
- // No super initializer found. Try to find the default constructor if
- // the class is not Object.
- ClassElement enclosingClass = constructor.enclosingElement;
- ClassElement superClass = enclosingClass.superclass;
- ClassElement objectElement = compiler.coreLibrary.find(Types.OBJECT);
- if (enclosingClass != objectElement) {
- assert(superClass !== null);
- assert(superClass.isResolved);
- nextConstructor = superClass.lookupConstructor(superClass.name);
- if (nextConstructor === null) {
- compiler.internalError("no default constructor available");
- }
- }
- }
- }
+ inlineInitializers(functionElement, constructors, fieldValues);
+
// Call the JavaScript constructor with the fields as argument.
// TODO(floitsch,karlklose): move this code to ClassElement and share with
// the emitter.
« no previous file with comments | « no previous file | tests/co19/co19-leg.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698