| Index: lib/compiler/implementation/ssa/builder.dart
|
| diff --git a/lib/compiler/implementation/ssa/builder.dart b/lib/compiler/implementation/ssa/builder.dart
|
| index 9d4e97fdbfbe702a9daba1f8c3fbc421525d5f77..75f5d9466774eeb8ffb694e84c0f7836e3e97191 100644
|
| --- a/lib/compiler/implementation/ssa/builder.dart
|
| +++ b/lib/compiler/implementation/ssa/builder.dart
|
| @@ -803,45 +803,6 @@ class SsaBuilder implements Visitor {
|
| return bodyElement;
|
| }
|
|
|
| - void inlineSuperOrRedirect(FunctionElement constructor,
|
| - Selector selector,
|
| - Link<Node> arguments,
|
| - List<FunctionElement> constructors,
|
| - Map<Element, HInstruction> fieldValues) {
|
| - constructors.addLast(constructor);
|
| -
|
| - List<HInstruction> compiledArguments = new List<HInstruction>();
|
| - bool succeeded = addStaticSendArgumentsToList(selector,
|
| - arguments,
|
| - constructor,
|
| - compiledArguments);
|
| - if (!succeeded) {
|
| - // Non-matching super and redirects are compile-time errors and thus
|
| - // checked by the resolver.
|
| - compiler.internalError(
|
| - "Parameters and arguments didn't match for super/redirect call",
|
| - element: constructor);
|
| - }
|
| -
|
| - int index = 0;
|
| - FunctionParameters parameters = constructor.computeParameters(compiler);
|
| - parameters.forEachParameter((Element parameter) {
|
| - HInstruction argument = compiledArguments[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.
|
| @@ -849,13 +810,15 @@ 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 buildInitializers(FunctionElement constructor,
|
| - List<FunctionElement> constructors,
|
| - Map<Element, HInstruction> fieldValues) {
|
| + 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);
|
|
|
| - bool foundSuperOrRedirect = false;
|
| -
|
| if (functionNode.initializers !== null) {
|
| Link<Node> initializers = functionNode.initializers.nodes;
|
| for (Link<Node> link = initializers; !link.isEmpty(); link = link.tail) {
|
| @@ -865,12 +828,26 @@ class SsaBuilder implements Visitor {
|
| Send call = link.head;
|
| assert(Initializers.isSuperConstructorCall(call) ||
|
| Initializers.isConstructorRedirect(call));
|
| - FunctionElement target = elements[call];
|
| - Selector selector = elements.getSelector(call);
|
| - Link<Node> arguments = call.arguments;
|
| - inlineSuperOrRedirect(target, selector, arguments, constructors,
|
| - fieldValues);
|
| - foundSuperOrRedirect = true;
|
| + 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;
|
| @@ -882,7 +859,7 @@ class SsaBuilder implements Visitor {
|
| }
|
| }
|
|
|
| - if (!foundSuperOrRedirect) {
|
| + if (!initializedSuper) {
|
| // No super initializer found. Try to find the default constructor if
|
| // the class is not Object.
|
| ClassElement enclosingClass = constructor.enclosingElement;
|
| @@ -890,17 +867,16 @@ class SsaBuilder implements Visitor {
|
| if (enclosingClass != compiler.objectClass) {
|
| assert(superClass !== null);
|
| assert(superClass.isResolved);
|
| - FunctionElement target = superClass.lookupConstructor(superClass.name);
|
| - if (target === null) {
|
| + FunctionElement nextConstructor =
|
| + superClass.lookupConstructor(superClass.name);
|
| + if (nextConstructor === null) {
|
| compiler.internalError("no default constructor available");
|
| }
|
| - inlineSuperOrRedirect(target,
|
| - Selector.INVOCATION_0,
|
| - const EmptyLink<Node>(),
|
| - constructors,
|
| - fieldValues);
|
| + inlineInitializers(nextConstructor, constructors, fieldValues);
|
| }
|
| }
|
| +
|
| + elements = oldElements;
|
| }
|
|
|
| /**
|
| @@ -936,11 +912,11 @@ class SsaBuilder implements Visitor {
|
|
|
| final Map<FunctionElement, TreeElements> constructorElements =
|
| compiler.resolver.constructorElements;
|
| - List<FunctionElement> constructors = <FunctionElement>[functionElement];
|
| + List<FunctionElement> constructors = new List<FunctionElement>();
|
|
|
| // Analyze the constructor and all referenced constructors and collect
|
| // initializers and constructor bodies.
|
| - buildInitializers(functionElement, constructors, fieldValues);
|
| + inlineInitializers(functionElement, constructors, fieldValues);
|
|
|
| // Call the JavaScript constructor with the fields as argument.
|
| List<HInstruction> constructorArguments = <HInstruction>[];
|
| @@ -1802,11 +1778,7 @@ class SsaBuilder implements Visitor {
|
| }
|
| }
|
|
|
| - /**
|
| - * Returns true if the arguments were compatible with the function signature.
|
| - */
|
| - bool addStaticSendArgumentsToList(Selector selector,
|
| - Link<Node> arguments,
|
| + void addStaticSendArgumentsToList(Send node,
|
| FunctionElement element,
|
| List<HInstruction> list) {
|
| HInstruction compileArgument(Node argument) {
|
| @@ -1819,9 +1791,16 @@ class SsaBuilder implements Visitor {
|
| return graph.addConstant(constant);
|
| }
|
|
|
| + Selector selector = elements.getSelector(node);
|
| FunctionParameters parameters = element.computeParameters(compiler);
|
| - return selector.addArgumentsToList(arguments, list, parameters,
|
| - compileArgument, compileConstant);
|
| + bool succeeded = selector.addSendArgumentsToList(node, list, parameters,
|
| + compileArgument,
|
| + compileConstant);
|
| + if (!succeeded) {
|
| + // TODO(ngeoffray): Match the VM behavior and throw an
|
| + // exception at runtime.
|
| + compiler.cancel('Unimplemented non-matching static call', node: node);
|
| + }
|
| }
|
|
|
| void addGenericSendArgumentsToList(Link<Node> link, List<HInstruction> list) {
|
| @@ -2087,13 +2066,7 @@ class SsaBuilder implements Visitor {
|
| var inputs = <HInstruction>[target, context];
|
| if (element.kind == ElementKind.FUNCTION ||
|
| element.kind == ElementKind.GENERATIVE_CONSTRUCTOR) {
|
| - bool succeeded = addStaticSendArgumentsToList(selector, node.arguments,
|
| - element, inputs);
|
| - if (!succeeded) {
|
| - // TODO(ngeoffray): Match the VM behavior and throw an
|
| - // exception at runtime.
|
| - compiler.cancel('Unimplemented non-matching static call', node);
|
| - }
|
| + addStaticSendArgumentsToList(node, element, inputs);
|
| push(new HInvokeSuper(selector, inputs));
|
| } else {
|
| target = new HInvokeSuper(Selector.GETTER, inputs);
|
| @@ -2118,13 +2091,7 @@ class SsaBuilder implements Visitor {
|
| inputs.add(target);
|
| if (element.kind == ElementKind.FUNCTION ||
|
| element.kind == ElementKind.GENERATIVE_CONSTRUCTOR) {
|
| - bool succeeded = addStaticSendArgumentsToList(selector, node.arguments,
|
| - element, inputs);
|
| - if (!succeeded) {
|
| - // TODO(ngeoffray): Match the VM behavior and throw an
|
| - // exception at runtime.
|
| - compiler.cancel('Unimplemented non-matching static call', node: node);
|
| - }
|
| + addStaticSendArgumentsToList(node, element, inputs);
|
| push(new HInvokeStatic(selector, inputs));
|
| } else {
|
| if (element.kind == ElementKind.GETTER) {
|
|
|