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

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

Issue 9930005: Use default values of named arguments when invoking the default super constructor. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Report bad static calls with position (regression fix). Created 8 years, 8 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: lib/compiler/implementation/ssa/builder.dart
diff --git a/lib/compiler/implementation/ssa/builder.dart b/lib/compiler/implementation/ssa/builder.dart
index 995a244337dc3cad8ea58310f6310e68baae0a87..14af2feeb10a0cac90e96e63d918fba23e6b7346 100644
--- a/lib/compiler/implementation/ssa/builder.dart
+++ b/lib/compiler/implementation/ssa/builder.dart
@@ -803,6 +803,40 @@ 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);
+ assert(succeeded);
ngeoffray 2012/04/16 12:24:02 Please add a comment why this is an assert and not
floitsch 2012/04/16 14:23:14 changed to internal error.
+
+ 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;
+ return true;
+ }
/**
* Run through the initializers and inline all field initializers. Recursively
* inlines super initializers.
@@ -810,15 +844,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) {
@@ -828,26 +860,12 @@ 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];
+ Selector selector = elements.getSelector(call);
+ Link<Node> arguments = call.arguments;
+ inlineSuperOrRedirect(target, selector, arguments, constructors,
+ fieldValues);
+ foundSuperOrRedirect = true;
} else {
// A field initializer.
SendSet init = link.head;
@@ -859,7 +877,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;
@@ -867,16 +885,17 @@ 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");
ngeoffray 2012/04/16 12:24:02 Could you also update the resolver to report the '
floitsch 2012/04/16 14:23:14 The resolver does the right thing now.
}
- inlineInitializers(nextConstructor, constructors, fieldValues);
+ inlineSuperOrRedirect(target,
+ Selector.INVOCATION_0,
+ const EmptyLink<Node>(),
+ constructors,
+ fieldValues);
}
}
-
- elements = oldElements;
}
/**
@@ -912,11 +931,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>[];
@@ -1774,7 +1793,11 @@ class SsaBuilder implements Visitor {
}
}
- void addStaticSendArgumentsToList(Send node,
+ /**
+ * Returns true if the arguments were compatible with the function signature.
+ */
+ bool addStaticSendArgumentsToList(Selector selector,
+ Link<Node> arguments,
FunctionElement element,
List<HInstruction> list) {
HInstruction compileArgument(Node argument) {
@@ -1787,16 +1810,9 @@ class SsaBuilder implements Visitor {
return graph.addConstant(constant);
}
- Selector selector = elements.getSelector(node);
FunctionParameters parameters = element.computeParameters(compiler);
- 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);
- }
+ return selector.addArgumentsToList(arguments, list, parameters,
+ compileArgument, compileConstant);
}
void addGenericSendArgumentsToList(Link<Node> link, List<HInstruction> list) {
@@ -2061,7 +2077,13 @@ class SsaBuilder implements Visitor {
var inputs = <HInstruction>[target, context];
if (element.kind == ElementKind.FUNCTION ||
element.kind == ElementKind.GENERATIVE_CONSTRUCTOR) {
- addStaticSendArgumentsToList(node, element, inputs);
+ 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);
+ }
push(new HInvokeSuper(selector, inputs));
} else {
target = new HInvokeSuper(Selector.GETTER, inputs);
@@ -2086,7 +2108,13 @@ class SsaBuilder implements Visitor {
inputs.add(target);
if (element.kind == ElementKind.FUNCTION ||
element.kind == ElementKind.GENERATIVE_CONSTRUCTOR) {
- addStaticSendArgumentsToList(node, element, inputs);
+ 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);
+ }
push(new HInvokeStatic(selector, inputs));
} else {
if (element.kind == ElementKind.GETTER) {

Powered by Google App Engine
This is Rietveld 408576698