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

Unified Diff: frog/leg/ssa/builder.dart

Issue 9301038: Support named arguments for statically resolved calls. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: '' Created 8 years, 11 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
« no previous file with comments | « frog/leg/resolver.dart ('k') | frog/leg/ssa/codegen.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: frog/leg/ssa/builder.dart
===================================================================
--- frog/leg/ssa/builder.dart (revision 3723)
+++ frog/leg/ssa/builder.dart (working copy)
@@ -208,7 +208,6 @@
FunctionExpression function = functionElement.parseNode(compiler);
NodeList initializers = function.initializers;
- NodeList parameters = function.parameters;
// Run through the initializers.
if (initializers !== null) {
for (Link<Node> link = initializers.nodes;
@@ -250,15 +249,11 @@
List bodyCallInputs = <HInstruction>[];
bodyCallInputs.add(newObject);
- for (Link link = parameters.nodes; !link.isEmpty(); link = link.tail) {
- Link<Node> nodeLink = link.head.definitions.nodes;
- // We expect exactly one identifier.
- assert(!nodeLink.isEmpty() && nodeLink.tail.isEmpty());
- Node current = nodeLink.head;
- Element parameterElement = elements[current];
+ FunctionParameters parameters = functionElement.computeParameters(compiler);
+ parameters.forEachParameter((Element parameterElement) {
HInstruction currentValue = definitions[parameterElement];
bodyCallInputs.add(currentValue);
- }
+ });
add(new HInvokeDynamicMethod(null, methodName, bodyCallInputs));
close(new HReturn(newObject)).addSuccessor(graph.exit);
return closeFunction();
@@ -887,7 +882,84 @@
}
}
- addVisitedSendArgumentsToList(Link<Node> link, List<HInstruction> list) {
+ void addDynamicSendArgumentsToList(Send node, List<HInstruction> list) {
+ Selector selector = elements.getSelector(node);
+ if (selector.namedArgumentCount == 0) {
+ addGenericSendArgumentsToList(node.arguments, list);
+ } else {
+ compiler.cancel(
+ 'Unimplemented named argument for dynamic sends', node: node);
+ }
+ }
+
+ void addStaticSendArgumentsToList(Send node,
+ FunctionElement element,
+ List<HInstruction> list) {
+ Selector selector = elements.getSelector(node);
+ if (!selector.applies(compiler, element)) {
+ // TODO(ngeoffray): Match the VM behavior and throw an
+ // exception at runtime.
+ compiler.cancel('Unimplemented non-matching static call', node: node);
+ } else if (selector.namedArgumentCount == 0) {
+ addGenericSendArgumentsToList(node.arguments, list);
+ } else {
+ // If there are named arguments, provide them in the order
+ // expected by the called function, which is the source order.
+ FunctionParameters parameters = element.computeParameters(compiler);
+
+ // Visit positional arguments and add them to the list.
+ Link<Node> arguments = node.arguments;
+ int positionalArgumentCount = selector.positionalArgumentCount;
+ for (int i = 0;
+ i < positionalArgumentCount;
+ arguments = arguments.tail, i++) {
+ visit(arguments.head);
+ list.add(pop());
+ }
+
+ // Visit named arguments and add them into a temporary list.
+ List<HInstruction> namedArguments = <HInstruction>[];
+ for (; !arguments.isEmpty(); arguments = arguments.tail) {
+ visit(arguments.head);
+ namedArguments.add(pop());
+ }
+
+ Link<Element> remainingNamedParameters = parameters.optionalParameters;
+ // Skip the optional parameters that have been given in the
+ // positional arguments.
+ for (int i = parameters.requiredParameterCount;
+ i < positionalArgumentCount;
+ i++) {
+ remainingNamedParameters = remainingNamedParameters.tail;
+ }
+
+ // Loop over the remaining named parameters, and try to find
+ // their values: either in the temporary list or using the
+ // default value.
+ for (;
+ !remainingNamedParameters.isEmpty();
+ remainingNamedParameters = remainingNamedParameters.tail) {
+ Element parameter = remainingNamedParameters.head;
+ int foundIndex = -1;
+ for (int i = 0; i < selector.namedArguments.length; i++) {
+ SourceString name = selector.namedArguments[i];
+ if (name == parameter.name) {
+ foundIndex = i;
+ break;
+ }
+ }
+ if (foundIndex != -1) {
+ list.add(namedArguments[foundIndex]);
+ } else {
+ // TODO(ngeoffray): Add the default value.
+ push(new HLiteral(null, HType.UNKNOWN));
+ list.add(pop());
+ }
+ }
+ }
+ }
+
+ void addGenericSendArgumentsToList(Link<Node> link, List<HInstruction> list) {
for (; !link.isEmpty(); link = link.tail) {
visit(link.head);
list.add(pop());
@@ -926,7 +998,7 @@
inputs.add(target);
visit(node.receiver);
inputs.add(pop());
- addVisitedSendArgumentsToList(node.arguments, inputs);
+ addGenericSendArgumentsToList(node.arguments, inputs);
push(new HInvokeInterceptor(selector, dartMethodName, false, inputs));
return;
}
@@ -942,7 +1014,7 @@
inputs.add(pop());
}
- addVisitedSendArgumentsToList(node.arguments, inputs);
+ addDynamicSendArgumentsToList(node, inputs);
// The first entry in the inputs list is the receiver.
push(new HInvokeDynamicMethod(selector, dartMethodName, inputs));
@@ -969,7 +1041,7 @@
}
var inputs = <HInstruction>[];
inputs.add(closureTarget);
- addVisitedSendArgumentsToList(node.arguments, inputs);
+ addDynamicSendArgumentsToList(node, inputs);
push(new HInvokeClosure(selector, inputs));
}
@@ -983,7 +1055,7 @@
// which is the foreign code.
link = link.tail.tail;
List<HInstruction> inputs = <HInstruction>[];
- addVisitedSendArgumentsToList(link, inputs);
+ addGenericSendArgumentsToList(link, inputs);
LiteralString type = node.arguments.head;
LiteralString literal = node.arguments.tail.head;
compiler.ensure(literal is LiteralString);
@@ -1006,7 +1078,7 @@
if (!node.arguments.tail.isEmpty()) {
compiler.cancel('More than one expression in JS_HAS_EQUALS()');
}
- addVisitedSendArgumentsToList(node.arguments, inputs);
+ addGenericSendArgumentsToList(node.arguments, inputs);
String name = compiler.namer.instanceMethodName(
Namer.OPERATOR_EQUALS, 1);
push(new HForeign(
@@ -1028,7 +1100,7 @@
}
add(target);
var inputs = <HInstruction>[target, context];
- addVisitedSendArgumentsToList(node.arguments, inputs);
+ addStaticSendArgumentsToList(node, element, inputs);
push(new HInvokeSuper(selector, inputs));
}
@@ -1039,7 +1111,7 @@
add(target);
var inputs = <HInstruction>[];
inputs.add(target);
- addVisitedSendArgumentsToList(node.arguments, inputs);
+ addStaticSendArgumentsToList(node, element, inputs);
push(new HInvokeStatic(selector, inputs));
}
@@ -1058,6 +1130,8 @@
// Example: f() with 'f' unbound.
// This can only happen inside an instance method.
visitDynamicSend(node);
+ } else if (element.kind == ElementKind.CLASS) {
+ compiler.internalError("Cannot generate code for send", node: node);
} else if (element.isInstanceMember()) {
// Example: f() with 'f' bound to instance method.
visitDynamicSend(node);
@@ -1412,7 +1486,7 @@
}
visitNamedArgument(NamedArgument node) {
- compiler.unimplemented('SsaBuilder.visitNamedArgument', node: node);
+ visit(node.expression);
}
visitSwitchStatement(SwitchStatement node) {
« no previous file with comments | « frog/leg/resolver.dart ('k') | frog/leg/ssa/codegen.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698