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

Unified Diff: sdk/lib/_internal/compiler/implementation/ssa/builder.dart

Issue 19754002: Rewrite how we handle synthesized constructors in the compiler. This was motivated by issue https:/… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 5 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
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

Powered by Google App Engine
This is Rietveld 408576698