| 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;
|
| }
|
| }
|
|
|