Chromium Code Reviews| Index: lib/compiler/implementation/ssa/builder.dart |
| diff --git a/lib/compiler/implementation/ssa/builder.dart b/lib/compiler/implementation/ssa/builder.dart |
| index b5238ba8b03ae695b76b249e04427d9f27b85d87..02dec7a91b4bd76317f706cbf26dbb0f84a6aaff 100644 |
| --- a/lib/compiler/implementation/ssa/builder.dart |
| +++ b/lib/compiler/implementation/ssa/builder.dart |
| @@ -800,6 +800,34 @@ class SsaBuilder implements Visitor { |
| return bodyElement; |
| } |
| + void inlineSuperOrRedirect(FunctionElement constructor, |
| + Send send, |
| + List<FunctionElement> constructors, |
| + Map<Element, HInstruction> fieldValues) { |
| + constructors.addLast(constructor); |
| + |
| + List<HInstruction> arguments = new List<HInstruction>(); |
| + addStaticSendArgumentsToList(send, constructor, arguments); |
| + |
| + int index = 0; |
| + FunctionParameters parameters = constructor.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; |
| + } |
| + }); |
| + |
| + // Build the initializers in the context of the new constructor. |
| + TreeElements oldElements = elements; |
| + elements = compiler.resolver.resolveMethodElement(constructor); |
| + buildInitializers(constructor, constructors, fieldValues); |
| + elements = oldElements; |
| + } |
| /** |
| * Run through the initializers and inline all field initializers. Recursively |
| * inlines super initializers. |
| @@ -807,15 +835,13 @@ class SsaBuilder implements Visitor { |
| * The constructors of the inlined initializers is added to [constructors] |
| * with sub constructors having a lower index than super constructors. |
| */ |
| - 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); |
| + void buildInitializers(FunctionElement constructor, |
| + List<FunctionElement> constructors, |
| + Map<Element, HInstruction> fieldValues) { |
| FunctionExpression functionNode = constructor.parseNode(compiler); |
| + bool foundSuperOrRedirect = false; |
| + |
| if (functionNode.initializers !== null) { |
| Link<Node> initializers = functionNode.initializers.nodes; |
| for (Link<Node> link = initializers; !link.isEmpty(); link = link.tail) { |
| @@ -825,26 +851,9 @@ class SsaBuilder implements Visitor { |
| 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; |
| + FunctionElement target = elements[call]; |
| + inlineSuperOrRedirect(target, call, constructors, fieldValues); |
| + foundSuperOrRedirect = true; |
| } else { |
| // A field initializer. |
| SendSet init = link.head; |
| @@ -856,7 +865,7 @@ class SsaBuilder implements Visitor { |
| } |
| } |
| - if (!initializedSuper) { |
| + if (!foundSuperOrRedirect) { |
| // No super initializer found. Try to find the default constructor if |
| // the class is not Object. |
| ClassElement enclosingClass = constructor.enclosingElement; |
| @@ -864,16 +873,15 @@ class SsaBuilder implements Visitor { |
| if (enclosingClass != compiler.objectClass) { |
| assert(superClass !== null); |
| assert(superClass.isResolved); |
| - FunctionElement nextConstructor = |
| - superClass.lookupConstructor(superClass.name); |
| - if (nextConstructor === null) { |
| + FunctionElement target = superClass.lookupConstructor(superClass.name); |
| + if (target === null) { |
| compiler.internalError("no default constructor available"); |
| } |
| - inlineInitializers(nextConstructor, constructors, fieldValues); |
| + NodeList emptyNodeList = new NodeList(nodes: const EmptyLink()); |
| + Send syntheticSend = new Send(null, null, emptyNodeList); |
| + inlineSuperOrRedirect(target, syntheticSend, constructors, fieldValues); |
| } |
| } |
| - |
| - elements = oldElements; |
| } |
| /** |
| @@ -909,11 +917,11 @@ class SsaBuilder implements Visitor { |
| final Map<FunctionElement, TreeElements> constructorElements = |
| compiler.resolver.constructorElements; |
| - List<FunctionElement> constructors = new List<FunctionElement>(); |
| + List<FunctionElement> constructors = <FunctionElement>[functionElement]; |
| // Analyze the constructor and all referenced constructors and collect |
| // initializers and constructor bodies. |
| - inlineInitializers(functionElement, constructors, fieldValues); |
| + buildInitializers(functionElement, constructors, fieldValues); |
| // Call the JavaScript constructor with the fields as argument. |
| List<HInstruction> constructorArguments = <HInstruction>[]; |
| @@ -1750,6 +1758,12 @@ class SsaBuilder implements Visitor { |
| } |
| Selector selector = elements.getSelector(node); |
| + // For an implicit super call we construct a synthetic send which is not |
| + // in the elements. |
| + if (selector == null) { |
| + assert(node.argumentsNode.isEmpty()); |
| + selector = Selector.INVOCATION_0; |
| + } |
|
ngeoffray
2012/03/30 09:10:03
I think the creation of the synthethized node, and
floitsch
2012/03/30 18:18:28
Not sure. (I changed this line from "I disagree",
|
| FunctionParameters parameters = element.computeParameters(compiler); |
| bool succeeded = selector.addSendArgumentsToList(node, list, parameters, |
| compileArgument, |