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

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

Issue 278823002: dart2dart: Method and constructor calls in new backend. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Bailout on super receiver. Update status for test case that no longer fails. Created 6 years, 7 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library dart2js.ir_builder; 5 library dart2js.ir_builder;
6 6
7 import 'ir_nodes.dart' as ir; 7 import 'ir_nodes.dart' as ir;
8 import '../elements/elements.dart'; 8 import '../elements/elements.dart';
9 import '../dart2jslib.dart'; 9 import '../dart2jslib.dart';
10 import '../dart_types.dart'; 10 import '../dart_types.dart';
11 import '../source_file.dart'; 11 import '../source_file.dart';
12 import '../tree/tree.dart' as ast; 12 import '../tree/tree.dart' as ast;
13 import '../scanner/scannerlib.dart' show Token; 13 import '../scanner/scannerlib.dart' show Token, isUserDefinableOperator;
14 import '../dart_backend/dart_backend.dart' show DartBackend; 14 import '../dart_backend/dart_backend.dart' show DartBackend;
15 import 'ir_pickler.dart' show Unpickler, IrConstantPool; 15 import 'ir_pickler.dart' show Unpickler, IrConstantPool;
16 import '../universe/universe.dart' show SelectorKind;
16 17
17 /** 18 /**
18 * This task iterates through all resolved elements and builds [ir.Node]s. The 19 * This task iterates through all resolved elements and builds [ir.Node]s. The
19 * nodes are stored in the [nodes] map and accessible through [hasIr] and 20 * nodes are stored in the [nodes] map and accessible through [hasIr] and
20 * [getIr]. 21 * [getIr].
21 * 22 *
22 * The functionality of the IrNodes is added gradually, therefore elements might 23 * The functionality of the IrNodes is added gradually, therefore elements might
23 * have an IR or not, depending on the language features that are used. For 24 * have an IR or not, depending on the language features that are used. For
24 * elements that do have an IR, the tree [ast.Node]s and the [Token]s are not 25 * elements that do have an IR, the tree [ast.Node]s and the [Token]s are not
25 * used in the rest of the compilation. This is ensured by setting the element's 26 * used in the rest of the compilation. This is ensured by setting the element's
(...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after
496 } 497 }
497 498
498 499
499 ir.Primitive visitLiteralNull(ast.LiteralNull node) { 500 ir.Primitive visitLiteralNull(ast.LiteralNull node) {
500 assert(isOpen); 501 assert(isOpen);
501 ir.Constant constant = new ir.Constant(constantSystem.createNull()); 502 ir.Constant constant = new ir.Constant(constantSystem.createNull());
502 add(new ir.LetPrim(constant)); 503 add(new ir.LetPrim(constant));
503 return constant; 504 return constant;
504 } 505 }
505 506
506 // TODO(kmillikin): other literals. Strings require quoting and escaping 507 ir.Primitive visitLiteralString(ast.LiteralString node) {
507 // in the Dart backend. 508 assert(isOpen);
508 // LiteralString 509 ir.Constant constant =
510 new ir.Constant(constantSystem.createString(node.dartString));
511 add(new ir.LetPrim(constant));
512 return constant;
513 }
514
515 // TODO(kmillikin): other literals.
509 // LiteralList 516 // LiteralList
510 // LiteralMap 517 // LiteralMap
511 // LiteralMapEntry 518 // LiteralMapEntry
512 // LiteralSymbol 519 // LiteralSymbol
513 520
514 ir.Primitive visitParenthesizedExpression( 521 ir.Primitive visitParenthesizedExpression(
515 ast.ParenthesizedExpression node) { 522 ast.ParenthesizedExpression node) {
516 assert(isOpen); 523 assert(isOpen);
517 return visit(node.expression); 524 return visit(node.expression);
518 } 525 }
519 526
520 // ==== Sends ==== 527 // ==== Sends ====
521 ir.Primitive visitAssert(ast.Send node) { 528 ir.Primitive visitAssert(ast.Send node) {
522 assert(isOpen); 529 assert(isOpen);
523 return giveup(); 530 return giveup();
524 } 531 }
525 532
526 ir.Primitive visitClosureSend(ast.Send node) { 533 ir.Primitive visitClosureSend(ast.Send node) {
527 assert(isOpen); 534 assert(isOpen);
528 return giveup(); 535 return giveup();
529 } 536 }
530 537
531 ir.Primitive visitDynamicSend(ast.Send node) { 538 ir.Primitive visitDynamicSend(ast.Send node) {
539 if (node.receiver == null || node.receiver.isSuper()) {
540 return giveup();
541 }
532 assert(isOpen); 542 assert(isOpen);
Kevin Millikin (Google) 2014/05/09 10:21:22 Move the assert up above the call to giveup.
533 return giveup(); 543 Selector selector = elements.getSelector(node);
544 ir.Primitive receiver = visit(node.receiver);
545 List arguments = node.arguments.toList(growable:false)
Kevin Millikin (Google) 2014/05/09 10:21:22 This won't really handle optional/default argument
546 .map(visit).toList(growable:false);
547 ir.Parameter v = new ir.Parameter(null);
548 ir.Continuation k = new ir.Continuation([v]);
549 ir.Expression invoke =
550 new ir.InvokeMethod(receiver, selector, k, arguments);
551 add(new ir.LetCont(k, invoke));
552 return v;
534 } 553 }
535 554
536 ir.Primitive visitGetterSend(ast.Send node) { 555 ir.Primitive visitGetterSend(ast.Send node) {
537 assert(isOpen); 556 assert(isOpen);
538 Element element = elements[node]; 557 Element element = elements[node];
539 if (!Elements.isLocal(element)) return giveup(); 558 if (Elements.isLocal(element)) {
540 int index = variableIndex[element]; 559 int index = variableIndex[element];
541 ir.Primitive value = assignedVars[index]; 560 ir.Primitive value = assignedVars[index];
542 return value == null ? freeVars[index] : value; 561 return value == null ? freeVars[index] : value;
562 } else if (Elements.isInstanceField(element)) {
563 ir.Primitive receiver = visit(node.receiver);
564 ir.Parameter v = new ir.Parameter(null);
565 ir.Continuation k = new ir.Continuation([v]);
566 Selector selector = elements.getSelector(node);
567 assert(selector.kind == SelectorKind.GETTER);
568 ir.InvokeMethod invoke = new ir.InvokeMethod(receiver, selector, k, []);
569 add(new ir.LetCont(k, invoke));
570 return v;
571 } else {
572 // TODO(asgerf): static and top-level
573 // NOTE: Index-getters are OperatorSends, not GetterSends
574 return giveup();
575 }
543 } 576 }
544 577
545 ir.Primitive visitOperatorSend(ast.Send node) { 578 ir.Primitive visitOperatorSend(ast.Send node) {
546 assert(isOpen); 579 ast.Operator selectorNode = node.selector;
547 return giveup(); 580 if (!isUserDefinableOperator(selectorNode.source)) {
581 return giveup();
582 } else {
583 return visitDynamicSend(node);
584 }
548 } 585 }
549 586
550 // Build(StaticSend(f, arguments), C) = C[C'[InvokeStatic(f, xs)]] 587 // Build(StaticSend(f, arguments), C) = C[C'[InvokeStatic(f, xs)]]
551 // where (C', xs) = arguments.fold(Build, C) 588 // where (C', xs) = arguments.fold(Build, C)
552 ir.Primitive visitStaticSend(ast.Send node) { 589 ir.Primitive visitStaticSend(ast.Send node) {
553 assert(isOpen); 590 assert(isOpen);
554 Element element = elements[node]; 591 Element element = elements[node];
555 // TODO(lry): support static fields. (separate IR instruction?) 592 // TODO(lry): support static fields. (separate IR instruction?)
556 if (element.isField || element.isGetter) return giveup(); 593 if (element.isField || element.isGetter) return giveup();
557 // TODO(kmillikin): support static setters. 594 // TODO(kmillikin): support static setters.
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
596 } 633 }
597 634
598 ir.Primitive visitTypeReferenceSend(ast.Send node) { 635 ir.Primitive visitTypeReferenceSend(ast.Send node) {
599 assert(isOpen); 636 assert(isOpen);
600 return giveup(); 637 return giveup();
601 } 638 }
602 639
603 ir.Primitive visitSendSet(ast.SendSet node) { 640 ir.Primitive visitSendSet(ast.SendSet node) {
604 assert(isOpen); 641 assert(isOpen);
605 Element element = elements[node]; 642 Element element = elements[node];
606 if (!Elements.isLocal(element)) return giveup();
607 if (node.assignmentOperator.source != '=') return giveup(); 643 if (node.assignmentOperator.source != '=') return giveup();
608 // Exactly one argument expected for a simple assignment. 644 if (Elements.isLocal(element)) {
609 assert(!node.arguments.isEmpty); 645 // Exactly one argument expected for a simple assignment.
610 assert(node.arguments.tail.isEmpty); 646 assert(!node.arguments.isEmpty);
611 ir.Primitive result = visit(node.arguments.head); 647 assert(node.arguments.tail.isEmpty);
612 assignedVars[variableIndex[element]] = result; 648 ir.Primitive result = visit(node.arguments.head);
613 return result; 649 assignedVars[variableIndex[element]] = result;
650 return result;
651 } else if (Elements.isStaticOrTopLevel(element)) {
652 // TODO(asgerf): static and top-level
653 return giveup();
654 } else if (Elements.isUnresolved(element)) {
655 return giveup();
656 } else {
657 // Setter or index-setter invocation
658 assert(node.receiver != null);
659 if (node.receiver.isSuper()) return giveup();
660
661 ir.Primitive receiver = visit(node.receiver);
662 ir.Parameter v = new ir.Parameter(null);
663 ir.Continuation k = new ir.Continuation([v]);
664 Selector selector = elements.getSelector(node);
665 assert(selector.kind == SelectorKind.SETTER ||
666 selector.kind == SelectorKind.INDEX);
667 List<ir.Definition> args = node.arguments.toList(growable:false)
668 .map(visit).toList(growable:false);
669 ir.InvokeMethod invoke = new ir.InvokeMethod(receiver, selector, k, args);
670 add(new ir.LetCont(k, invoke));
671 return v;
Kevin Millikin (Google) 2014/05/09 10:21:22 I actually think the better way to model this is t
672 }
673 }
674
675 ir.Primitive visitNewExpression(ast.NewExpression node) {
676 if (node.isConst) {
677 return giveup(); // TODO(asgerf): Const constructor call.
678 }
679 FunctionElement element = elements[node.send];
680 if (Elements.isUnresolved(element)) {
681 return giveup();
682 }
683 ast.Node selector = node.send.selector;
684 GenericType type = elements.getType(node);
685 ir.Parameter v = new ir.Parameter(null);
686 ir.Continuation k = new ir.Continuation([v]);
687 List<ir.Definition> args = node.send.arguments.toList(growable:false)
Kevin Millikin (Google) 2014/05/09 10:21:22 There can also be optional arguments here.
688 .map(visit).toList(growable:false);
689 ir.InvokeConstructor invoke = new ir.InvokeConstructor(
690 type,
691 element,
692 k,
693 args);
694 add(new ir.LetCont(k, invoke));
695 return v;
614 } 696 }
615 697
616 static final String ABORT_IRNODE_BUILDER = "IrNode builder aborted"; 698 static final String ABORT_IRNODE_BUILDER = "IrNode builder aborted";
617 699
618 ir.Primitive giveup() => throw ABORT_IRNODE_BUILDER; 700 ir.Primitive giveup() => throw ABORT_IRNODE_BUILDER;
619 701
620 ir.FunctionDefinition nullIfGiveup(ir.FunctionDefinition action()) { 702 ir.FunctionDefinition nullIfGiveup(ir.FunctionDefinition action()) {
621 try { 703 try {
622 return action(); 704 return action();
623 } catch(e) { 705 } catch(e) {
(...skipping 12 matching lines...) Expand all
636 bool visit(DartType type, Null _) => type.accept(this, null); 718 bool visit(DartType type, Null _) => type.accept(this, null);
637 719
638 bool visitType(DartType type, Null _) => false; 720 bool visitType(DartType type, Null _) => false;
639 721
640 bool visitVoidType(VoidType type, Null _) => true; 722 bool visitVoidType(VoidType type, Null _) => true;
641 723
642 // Currently, InterfaceType and TypedefType are supported so long as they 724 // Currently, InterfaceType and TypedefType are supported so long as they
643 // do not have type parameters. They are subclasses of GenericType. 725 // do not have type parameters. They are subclasses of GenericType.
644 bool visitGenericType(GenericType type, Null _) => !type.isGeneric; 726 bool visitGenericType(GenericType type, Null _) => !type.isGeneric;
645 } 727 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698