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

Unified Diff: sdk/lib/_internal/compiler/implementation/ir/ir_builder.dart

Issue 349923004: Add support for superSend to the new IR and dart backend. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Also handle implicit this, fix a typeerror. Created 6 years, 6 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/ir/ir_builder.dart
diff --git a/sdk/lib/_internal/compiler/implementation/ir/ir_builder.dart b/sdk/lib/_internal/compiler/implementation/ir/ir_builder.dart
index e80aa26c07ceefceb645a8e015afceec421ea788..ccee7aa1c863bdcbace5c0d8a9d9136921c147e0 100644
--- a/sdk/lib/_internal/compiler/implementation/ir/ir_builder.dart
+++ b/sdk/lib/_internal/compiler/implementation/ir/ir_builder.dart
@@ -812,6 +812,7 @@ class IrBuilder extends ResolvedVisitor<ir.Primitive> {
ir.Primitive visitIdentifier(ast.Identifier node) {
assert(isOpen);
+ // "this" is the only identifier that should be met by the visitor.
assert(node.isThis());
return lookupThis();
}
@@ -894,13 +895,31 @@ class IrBuilder extends ResolvedVisitor<ir.Primitive> {
return v;
}
+ /// If [node] is null, returns this.
+ /// If [node] is super, returns null (for special handling)
+ /// Otherwise visits [node] and returns the result.
+ ir.Primitive visitReceiver(ast.Expression node) {
+ if (node == null) return lookupThis();
+ if (node.isSuper()) return null;
+ return visit(node);
+ }
+
+ /// Makes an [InvokeMethod] unless [node.receiver.isSuper()], in that case
+ /// makes an [InvokeSuperMethod] ignoring [receiver].
+ ir.Expression createDynamicInvoke(ast.Send node,
+ Selector selector,
+ ir.Definition receiver,
+ ir.Continuation k,
+ List<ir.Definition> arguments) {
+ return node.receiver != null && node.receiver.isSuper()
+ ? new ir.InvokeSuperMethod(selector, k, arguments)
+ : new ir.InvokeMethod(receiver, selector, k, arguments);
+ }
+
ir.Primitive visitDynamicSend(ast.Send node) {
assert(isOpen);
- if (node.receiver == null || node.receiver.isSuper()) {
- return giveup(node, 'DynamicSend without receiver, or super receiver');
- }
Selector selector = elements.getSelector(node);
- ir.Primitive receiver = visit(node.receiver);
+ ir.Primitive receiver = visitReceiver(node.receiver);
List<ir.Primitive> arguments = new List<ir.Primitive>();
for (ast.Node n in node.arguments) {
arguments.add(visit(n));
@@ -908,7 +927,7 @@ class IrBuilder extends ResolvedVisitor<ir.Primitive> {
ir.Parameter v = new ir.Parameter(null);
ir.Continuation k = new ir.Continuation([v]);
ir.Expression invoke =
- new ir.InvokeMethod(receiver, selector, k, arguments);
+ createDynamicInvoke(node, selector, receiver, k, arguments);
add(new ir.LetCont(k, invoke));
return v;
}
@@ -919,14 +938,13 @@ class IrBuilder extends ResolvedVisitor<ir.Primitive> {
if (Elements.isLocal(element)) {
return lookupLocal(element);
} else if (element == null || Elements.isInstanceField(element)) {
- ir.Primitive receiver = node.receiver == null
- ? lookupThis()
- : visit(node.receiver);
+ ir.Primitive receiver = visitReceiver(node.receiver);
ir.Parameter v = new ir.Parameter(null);
ir.Continuation k = new ir.Continuation([v]);
Selector selector = elements.getSelector(node);
assert(selector.kind == SelectorKind.GETTER);
- ir.InvokeMethod invoke = new ir.InvokeMethod(receiver, selector, k, []);
+ ir.Expression invoke =
+ createDynamicInvoke(node, selector, receiver, k, []);
add(new ir.LetCont(k, invoke));
return v;
} else if (element.isField) {
@@ -1122,7 +1140,11 @@ class IrBuilder extends ResolvedVisitor<ir.Primitive> {
ir.Primitive visitSuperSend(ast.Send node) {
assert(isOpen);
- return giveup(node, 'SuperSend');
+ if (node.isPropertyAccess) {
+ return visitGetterSend(node);
+ } else {
+ return visitDynamicSend(node);
+ }
}
ir.Primitive visitTypeReferenceSend(ast.Send node) {
@@ -1174,35 +1196,25 @@ class IrBuilder extends ResolvedVisitor<ir.Primitive> {
new ir.InvokeStatic(element, selector, k, [arg]);
add(new ir.LetCont(k, invoke));
return arg;
- } else if (node.receiver == null) {
- // Nodes that fall in this case:
- // - Unresolved top-level
- // - Assignment to final variable (will not be resolved)
- return giveup(node, 'SendSet: non-local, non-static, but no receiver');
} else {
if (element != null && Elements.isUnresolved(element)) {
- return giveup(node);
+ return giveup(node, 'SendSet: non-local, non-static, unresolved');
}
// Setter or index-setter invocation
- assert(node.receiver != null);
- if (node.receiver.isSuper()) return giveup(node, 'Super SendSet');
-
- ir.Primitive receiver = node.receiver == null
- ? lookupThis()
- : visit(node.receiver);
+ ir.Primitive receiver = visitReceiver(node.receiver);
ir.Parameter v = new ir.Parameter(null);
ir.Continuation k = new ir.Continuation([v]);
Selector selector = elements.getSelector(node);
assert(selector.kind == SelectorKind.SETTER ||
selector.kind == SelectorKind.INDEX);
- List<ir.Definition> args = node.arguments.mapToList(visit,
+ List<ir.Definition> arguments = node.arguments.mapToList(visit,
growable:false);
- ir.InvokeMethod invoke =
- new ir.InvokeMethod(receiver, selector, k, args);
+ ir.Expression invoke =
+ createDynamicInvoke(node, selector, receiver, k, arguments);
add(new ir.LetCont(k, invoke));
- return args.last;
+ return arguments.last;
}
} else if (ast.Operator.COMPLEX_OPERATORS.contains(op.source)) {
Element selectorElement = elements[node.selector];
@@ -1308,8 +1320,10 @@ class IrBuilder extends ResolvedVisitor<ir.Primitive> {
ir.FunctionDefinition nullIfGiveup(ir.FunctionDefinition action()) {
try {
return action();
- } catch(e) {
- if (e == ABORT_IRNODE_BUILDER) return null;
+ } catch(e, tr) {
+ if (e == ABORT_IRNODE_BUILDER) {
+ return null;
+ }
rethrow;
}
}

Powered by Google App Engine
This is Rietveld 408576698