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

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

Issue 9086010: closure calls (just the invocation part). (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Add test file. Created 8 years, 12 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: frog/leg/ssa/builder.dart
diff --git a/frog/leg/ssa/builder.dart b/frog/leg/ssa/builder.dart
index abf2a1211cd3b03a99c9ce39bc6983635d31b739..08d2e1a14edf7cdcc4c1aab6b8dea5149e2fcac2 100644
--- a/frog/leg/ssa/builder.dart
+++ b/frog/leg/ssa/builder.dart
@@ -848,45 +848,80 @@ class SsaBuilder implements Visitor {
} else if (node.isPropertyAccess) {
generateGetter(node, elements[node]);
} else {
+ final DYNAMIC = 0;
kasperl 2012/01/05 07:01:52 How about adding a few helper methods for some of
floitsch 2012/01/05 12:18:38 Done.
+ final INTERCEPTOR = 1;
+ final FOREIGN = 2;
+ final STATIC = 3;
+ final CLOSURE = 4;
Element element = elements[node];
- bool isInvokeDynamic = (element === null) || element.isInstanceMember();
- bool isForeign =
- (element !== null) && (element.kind === ElementKind.FOREIGN);
- bool isStatic = !isInvokeDynamic && !isForeign;
+ int callKind;
+ if (element === null) {
+ callKind = (node.selector.asIdentifier() === null) ? CLOSURE : DYNAMIC;
+ } else if (element.isInstanceMember()) {
+ callKind = DYNAMIC;
+ } else if (element.kind === ElementKind.FOREIGN) {
+ callKind = FOREIGN;
+ } else if (element.kind === ElementKind.VARIABLE ||
+ element.kind === ElementKind.PARAMETER) {
+ assert(node.receiver === null);
+ callKind = CLOSURE;
+ } else {
+ assert(!element.isInstanceMember());
+ callKind = STATIC;
+ }
Link<Node> link = node.arguments;
var inputs = <HInstruction>[];
SourceString dartMethodName;
Element interceptor;
- if (isInvokeDynamic) {
- dartMethodName = node.selector.asIdentifier().source;
- interceptor = interceptors.getStaticInterceptor(
- dartMethodName, node.argumentCount());
- if (interceptor != null) {
- HStatic target = new HStatic(interceptor);
+ switch (callKind) {
+ case DYNAMIC:
+ dartMethodName = node.selector.asIdentifier().source;
+ interceptor = interceptors.getStaticInterceptor(
+ dartMethodName, node.argumentCount());
+ if (interceptor != null) {
+ callKind = INTERCEPTOR;
+ HStatic target = new HStatic(interceptor);
+ add(target);
+ inputs.add(target);
+ visit(node.receiver);
+ inputs.add(pop());
+ } else if (node.receiver === null) {
+ HThis receiver = new HThis();
+ add(receiver);
+ inputs.add(receiver);
+ } else {
+ visit(node.receiver);
+ inputs.add(pop());
+ }
+ break;
+ case FOREIGN:
+ // If the invoke is on foreign code, don't visit the first
+ // argument, which is the type, and the second argument,
+ // which is the foreign code.
+ link = link.tail.tail;
+ break;
+ case STATIC:
+ HStatic target = new HStatic(element);
add(target);
inputs.add(target);
- visit(node.receiver);
- inputs.add(pop());
- isInvokeDynamic = false;
- } else if (node.receiver === null) {
- HThis receiver = new HThis();
- add(receiver);
- inputs.add(receiver);
- } else {
- visit(node.receiver);
- inputs.add(pop());
- }
- } else if (isForeign) {
- // If the invoke is on foreign code, don't visit the first
- // argument, which is the type, and the second argument,
- // which is the foreign code.
- link = link.tail.tail;
- } else {
- HStatic target = new HStatic(element);
- add(target);
- inputs.add(target);
+ break;
+ case CLOSURE:
+ HInstruction closureTarget;
+ if (element === null) {
+ visit(node.selector);
+ closureTarget = pop();
+ } else {
+ assert(element.kind === ElementKind.VARIABLE ||
+ element.kind === ElementKind.PARAMETER);
+ closureTarget = definitions[element];
+ assert(closureTarget !== null);
+ }
+ inputs.add(closureTarget);
+ break;
+ default:
+ unreachable("Unhandled callKind in SsaBuilder: $callKind"); break;
}
for (; !link.isEmpty(); link = link.tail) {
@@ -894,22 +929,34 @@ class SsaBuilder implements Visitor {
inputs.add(pop());
}
- if (isInvokeDynamic) {
- String jsMethodName = compiler.namer.instanceName(dartMethodName);
- // The first entry in the inputs list is the receiver.
- push(new HInvokeDynamicMethod(jsMethodName, inputs));
- } else if (isForeign) {
- LiteralString type = node.arguments.head;
- LiteralString literal = node.arguments.tail.head;
- compiler.ensure(literal is LiteralString);
- compiler.ensure(type is LiteralString);
- compiler.ensure(literal.value.stringValue[0] == '@');
- push(new HForeign(unquote(literal, 1), unquote(type, 0), inputs));
- } else if (interceptor != null) {
- push(new HInvokeInterceptor(dartMethodName.stringValue, false, inputs));
- } else {
- assert(isStatic);
- push(new HInvokeStatic(inputs));
+ switch (callKind) {
+ case DYNAMIC:
+ String jsMethodName = compiler.namer.instanceName(dartMethodName);
+ // The first entry in the inputs list is the receiver.
+ push(new HInvokeDynamicMethod(jsMethodName, inputs));
+ break;
+ case FOREIGN:
+ LiteralString type = node.arguments.head;
+ LiteralString literal = node.arguments.tail.head;
+ compiler.ensure(literal is LiteralString);
+ compiler.ensure(type is LiteralString);
+ compiler.ensure(literal.value.stringValue[0] == '@');
+ push(new HForeign(unquote(literal, 1), unquote(type, 0), inputs));
+ break;
+ case INTERCEPTOR:
+ assert(interceptor != null);
+ push(new HInvokeInterceptor(dartMethodName.stringValue, false,
+ inputs));
+ break;
+ case STATIC:
+ push(new HInvokeStatic(inputs));
+ break;
+ case CLOSURE:
+ String jsMethodName = compiler.namer.closureInvocationName();
+ push(new HInvokeDynamicMethod(jsMethodName, inputs));
+ break;
+ default:
+ unreachable("Unhandled callKind in SsaBuilder: $callKind"); break;
}
}
}

Powered by Google App Engine
This is Rietveld 408576698