| Index: sdk/lib/_internal/compiler/implementation/ssa/builder.dart
|
| ===================================================================
|
| --- sdk/lib/_internal/compiler/implementation/ssa/builder.dart (revision 25147)
|
| +++ sdk/lib/_internal/compiler/implementation/ssa/builder.dart (working copy)
|
| @@ -212,7 +212,7 @@
|
| * Invariant: [function] must be an implementation element.
|
| */
|
| void startFunction(Element element, Expression node) {
|
| - assert(invariant(node, element.isImplementation));
|
| + assert(invariant(element, element.isImplementation));
|
| Compiler compiler = builder.compiler;
|
| closureData = compiler.closureToClassMapper.computeClosureToClassMapping(
|
| element, node, builder.elements);
|
| @@ -1271,6 +1271,8 @@
|
| return false;
|
| }
|
|
|
| + if (element.isSynthesized) return true;
|
| +
|
| if (cachedCanBeInlined == true) return cachedCanBeInlined;
|
|
|
| int numParameters = function.functionSignature.parameterCount;
|
| @@ -1346,37 +1348,19 @@
|
| *
|
| * Invariant: [constructors] must contain only implementation elements.
|
| */
|
| - void inlineSuperOrRedirect(FunctionElement constructor,
|
| - Selector selector,
|
| - Link<Node> arguments,
|
| + void inlineSuperOrRedirect(FunctionElement callee,
|
| + List<HInstruction> compiledArguments,
|
| List<FunctionElement> constructors,
|
| Map<Element, HInstruction> fieldValues,
|
| - FunctionElement inlinedFromElement,
|
| - Node callNode) {
|
| - constructor = constructor.implementation;
|
| - compiler.withCurrentElement(constructor, () {
|
| - constructors.add(constructor);
|
| -
|
| - List<HInstruction> compiledArguments = new List<HInstruction>();
|
| - bool succeeded =
|
| - inlinedFrom(inlinedFromElement,
|
| - () => 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);
|
| - }
|
| -
|
| - ClassElement enclosingClass = constructor.getEnclosingClass();
|
| + FunctionElement caller) {
|
| + callee = callee.implementation;
|
| + compiler.withCurrentElement(callee, () {
|
| + constructors.add(callee);
|
| + ClassElement enclosingClass = callee.getEnclosingClass();
|
| if (backend.classNeedsRti(enclosingClass)) {
|
| // If [enclosingClass] needs RTI, we have to give a value to its
|
| // type parameters.
|
| - ClassElement currentClass = inlinedFromElement.getEnclosingClass();
|
| + ClassElement currentClass = caller.getEnclosingClass();
|
| // For a super constructor call, the type is the supertype of
|
| // [currentClass]. For a redirecting constructor, the type is
|
| // the current type. [InterfaceType.asInstanceOf] takes care
|
| @@ -1384,8 +1368,9 @@
|
| InterfaceType type = currentClass.thisType.asInstanceOf(enclosingClass);
|
| Link<DartType> typeVariables = enclosingClass.typeVariables;
|
| type.typeArguments.forEach((DartType argument) {
|
| - localsHandler.updateLocal(typeVariables.head.element,
|
| - analyzeTypeArgument(argument, callNode));
|
| + localsHandler.updateLocal(
|
| + typeVariables.head.element,
|
| + analyzeTypeArgument(argument));
|
| typeVariables = typeVariables.tail;
|
| });
|
| // If the supertype is a raw type, we need to set to null the
|
| @@ -1399,13 +1384,13 @@
|
| }
|
| }
|
|
|
| - inlinedFrom(constructor, () {
|
| - buildFieldInitializers(constructor.enclosingElement.implementation,
|
| + inlinedFrom(callee, () {
|
| + buildFieldInitializers(callee.enclosingElement.implementation,
|
| fieldValues);
|
| });
|
|
|
| int index = 0;
|
| - FunctionSignature params = constructor.computeSignature(compiler);
|
| + FunctionSignature params = callee.computeSignature(compiler);
|
| params.orderedForEachParameter((Element parameter) {
|
| HInstruction argument = compiledArguments[index++];
|
| // Because we are inlining the initializer, we must update
|
| @@ -1423,19 +1408,15 @@
|
|
|
| // Build the initializers in the context of the new constructor.
|
| TreeElements oldElements = elements;
|
| - if (constructor.isForwardingConstructor) {
|
| - constructor = constructor.targetConstructor;
|
| - }
|
| - elements =
|
| - compiler.enqueuer.resolution.getCachedElements(constructor);
|
| + elements = compiler.enqueuer.resolution.getCachedElements(callee);
|
| ClosureClassMap oldClosureData = localsHandler.closureData;
|
| - Node node = constructor.parseNode(compiler);
|
| + Node node = callee.parseNode(compiler);
|
| ClosureClassMap newClosureData =
|
| compiler.closureToClassMapper.computeClosureToClassMapping(
|
| - constructor, node, elements);
|
| + callee, node, elements);
|
| localsHandler.closureData = newClosureData;
|
| - localsHandler.enterScope(node, constructor);
|
| - buildInitializers(constructor, constructors, fieldValues);
|
| + localsHandler.enterScope(node, callee);
|
| + buildInitializers(callee, constructors, fieldValues);
|
| localsHandler.closureData = oldClosureData;
|
| elements = oldElements;
|
| });
|
| @@ -1455,30 +1436,56 @@
|
| List<FunctionElement> constructors,
|
| Map<Element, HInstruction> fieldValues) {
|
| assert(invariant(constructor, constructor.isImplementation));
|
| + if (constructor.isSynthesized) {
|
| + List<HInstruction> arguments = <HInstruction>[];
|
| + HInstruction compileArgument(Element element) {
|
| + return localsHandler.readLocal(element);
|
| + }
|
| +
|
| + Element target = constructor.targetConstructor.implementation;
|
| + Selector.addForwardingElementArgumentsToList(
|
| + constructor,
|
| + arguments,
|
| + target,
|
| + compileArgument,
|
| + handleConstantForOptionalParameter,
|
| + compiler);
|
| + inlineSuperOrRedirect(
|
| + target,
|
| + arguments,
|
| + constructors,
|
| + fieldValues,
|
| + constructor);
|
| + return;
|
| + }
|
| 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) {
|
| assert(link.head is Send);
|
| if (link.head is !SendSet) {
|
| // A super initializer or constructor redirection.
|
| + foundSuperOrRedirect = true;
|
| Send call = link.head;
|
| assert(Initializers.isSuperConstructorCall(call) ||
|
| Initializers.isConstructorRedirect(call));
|
| - FunctionElement target = elements[call];
|
| + FunctionElement target = elements[call].implementation;
|
| Selector selector = elements.getSelector(call);
|
| Link<Node> arguments = call.arguments;
|
| + List<HInstruction> compiledArguments = new List<HInstruction>();
|
| + inlinedFrom(constructor, () {
|
| + addStaticSendArgumentsToList(selector,
|
| + arguments,
|
| + target,
|
| + compiledArguments);
|
| + });
|
| inlineSuperOrRedirect(target,
|
| - selector,
|
| - arguments,
|
| + compiledArguments,
|
| constructors,
|
| fieldValues,
|
| - constructor,
|
| - call);
|
| - foundSuperOrRedirect = true;
|
| + constructor);
|
| } else {
|
| // A field initializer.
|
| SendSet init = link.head;
|
| @@ -1507,13 +1514,18 @@
|
| if (target == null) {
|
| compiler.internalError("no default constructor available");
|
| }
|
| + List<HInstruction> arguments = <HInstruction>[];
|
| + selector.addArgumentsToList(const Link<Node>(),
|
| + arguments,
|
| + target.implementation,
|
| + null,
|
| + handleConstantForOptionalParameter,
|
| + compiler);
|
| inlineSuperOrRedirect(target,
|
| - selector,
|
| - const Link<Node>(),
|
| + arguments,
|
| constructors,
|
| fieldValues,
|
| - constructor,
|
| - functionNode);
|
| + constructor);
|
| }
|
| }
|
| }
|
| @@ -2914,10 +2926,6 @@
|
| return pop();
|
| }
|
|
|
| - if (element.isForwardingConstructor) {
|
| - element = element.targetConstructor;
|
| - }
|
| -
|
| return selector.addArgumentsToList(arguments,
|
| list,
|
| element,
|
| @@ -3371,8 +3379,8 @@
|
| *
|
| * Invariant: [argument] must not be malformed in checked mode.
|
| */
|
| - HInstruction analyzeTypeArgument(DartType argument, Node currentNode) {
|
| - assert(invariant(currentNode,
|
| + HInstruction analyzeTypeArgument(DartType argument) {
|
| + assert(invariant(currentElement,
|
| !compiler.enableTypeAssertions || !argument.isMalformed,
|
| message: '$argument is malformed in checked mode'));
|
| if (argument == compiler.types.dynamicType || argument.isMalformed) {
|
| @@ -3398,7 +3406,7 @@
|
| if (!type.isRaw) {
|
| List<HInstruction> inputs = <HInstruction>[];
|
| type.typeArguments.forEach((DartType argument) {
|
| - inputs.add(analyzeTypeArgument(argument, currentNode));
|
| + inputs.add(analyzeTypeArgument(argument));
|
| });
|
| callSetRuntimeTypeInfo(type.element, inputs, newObject);
|
| }
|
| @@ -3461,13 +3469,6 @@
|
|
|
| Element constructor = elements[send];
|
| Selector selector = elements.getSelector(send);
|
| - if (constructor.isForwardingConstructor) {
|
| - compiler.unimplemented('forwarded constructor in named mixin application',
|
| - element: constructor.getEnclosingClass());
|
| - }
|
| - if (compiler.enqueuer.resolution.getCachedElements(constructor) == null) {
|
| - compiler.internalError("Unresolved element: $constructor", node: send);
|
| - }
|
| FunctionElement functionElement = constructor;
|
| constructor = functionElement.redirectionTarget;
|
|
|
| @@ -3508,7 +3509,7 @@
|
| if (backend.classNeedsRti(cls)) {
|
| Link<DartType> typeVariable = cls.typeVariables;
|
| type.typeArguments.forEach((DartType argument) {
|
| - inputs.add(analyzeTypeArgument(argument, send));
|
| + inputs.add(analyzeTypeArgument(argument));
|
| typeVariable = typeVariable.tail;
|
| });
|
| // Also add null to non-provided type variables to call the
|
|
|