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 |