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

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: Removed call to addArgumentsToList. 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 545 matching lines...) Expand 10 before | Expand all | Expand 10 after
571 } 572 }
572 573
573 574
574 ir.Primitive visitLiteralNull(ast.LiteralNull node) { 575 ir.Primitive visitLiteralNull(ast.LiteralNull node) {
575 assert(isOpen); 576 assert(isOpen);
576 ir.Constant constant = new ir.Constant(constantSystem.createNull()); 577 ir.Constant constant = new ir.Constant(constantSystem.createNull());
577 add(new ir.LetPrim(constant)); 578 add(new ir.LetPrim(constant));
578 return constant; 579 return constant;
579 } 580 }
580 581
581 // TODO(kmillikin): other literals. Strings require quoting and escaping 582 ir.Primitive visitLiteralString(ast.LiteralString node) {
582 // in the Dart backend. 583 assert(isOpen);
583 // LiteralString 584 ir.Constant constant =
585 new ir.Constant(constantSystem.createString(node.dartString));
586 add(new ir.LetPrim(constant));
587 return constant;
588 }
589
590 // TODO(kmillikin): other literals.
584 // LiteralList 591 // LiteralList
585 // LiteralMap 592 // LiteralMap
586 // LiteralMapEntry 593 // LiteralMapEntry
587 // LiteralSymbol 594 // LiteralSymbol
588 595
589 ir.Primitive visitParenthesizedExpression( 596 ir.Primitive visitParenthesizedExpression(
590 ast.ParenthesizedExpression node) { 597 ast.ParenthesizedExpression node) {
591 assert(isOpen); 598 assert(isOpen);
592 return visit(node.expression); 599 return visit(node.expression);
593 } 600 }
594 601
595 // ==== Sends ==== 602 // ==== Sends ====
596 ir.Primitive visitAssert(ast.Send node) { 603 ir.Primitive visitAssert(ast.Send node) {
597 assert(isOpen); 604 assert(isOpen);
598 return giveup(); 605 return giveup();
599 } 606 }
600 607
601 ir.Primitive visitClosureSend(ast.Send node) { 608 ir.Primitive visitClosureSend(ast.Send node) {
602 assert(isOpen); 609 assert(isOpen);
603 return giveup(); 610 return giveup();
604 } 611 }
605 612
606 ir.Primitive visitDynamicSend(ast.Send node) { 613 ir.Primitive visitDynamicSend(ast.Send node) {
607 assert(isOpen); 614 assert(isOpen);
608 return giveup(); 615 if (node.receiver == null || node.receiver.isSuper()) {
616 return giveup();
617 }
618 Selector selector = elements.getSelector(node);
619 ir.Primitive receiver = visit(node.receiver);
620 List arguments = node.arguments.toList(growable:false)
621 .map(visit).toList(growable:false);
622 ir.Parameter v = new ir.Parameter(null);
623 ir.Continuation k = new ir.Continuation([v]);
624 ir.Expression invoke =
625 new ir.InvokeMethod(receiver, selector, k, arguments);
626 add(new ir.LetCont(k, invoke));
627 return v;
609 } 628 }
610 629
611 ir.Primitive visitGetterSend(ast.Send node) { 630 ir.Primitive visitGetterSend(ast.Send node) {
612 assert(isOpen); 631 assert(isOpen);
613 Element element = elements[node]; 632 Element element = elements[node];
614 if (!Elements.isLocal(element)) return giveup(); 633 if (Elements.isLocal(element)) {
615 int index = variableIndex[element]; 634 int index = variableIndex[element];
616 ir.Primitive value = assignedVars[index]; 635 ir.Primitive value = assignedVars[index];
617 return value == null ? freeVars[index] : value; 636 return value == null ? freeVars[index] : value;
637 } else if (Elements.isInstanceField(element)) {
638 ir.Primitive receiver = visit(node.receiver);
639 ir.Parameter v = new ir.Parameter(null);
640 ir.Continuation k = new ir.Continuation([v]);
641 Selector selector = elements.getSelector(node);
642 assert(selector.kind == SelectorKind.GETTER);
643 ir.InvokeMethod invoke = new ir.InvokeMethod(receiver, selector, k, []);
644 add(new ir.LetCont(k, invoke));
645 return v;
646 } else {
647 // TODO(asgerf): static and top-level
648 // NOTE: Index-getters are OperatorSends, not GetterSends
649 return giveup();
650 }
618 } 651 }
619 652
620 ir.Primitive visitOperatorSend(ast.Send node) { 653 ir.Primitive visitOperatorSend(ast.Send node) {
621 assert(isOpen); 654 ast.Operator selectorNode = node.selector;
622 return giveup(); 655 if (!isUserDefinableOperator(selectorNode.source)) {
656 return giveup();
657 } else {
658 return visitDynamicSend(node);
659 }
623 } 660 }
624 661
625 // Build(StaticSend(f, arguments), C) = C[C'[InvokeStatic(f, xs)]] 662 // Build(StaticSend(f, arguments), C) = C[C'[InvokeStatic(f, xs)]]
626 // where (C', xs) = arguments.fold(Build, C) 663 // where (C', xs) = arguments.fold(Build, C)
627 ir.Primitive visitStaticSend(ast.Send node) { 664 ir.Primitive visitStaticSend(ast.Send node) {
628 assert(isOpen); 665 assert(isOpen);
629 Element element = elements[node]; 666 Element element = elements[node];
630 // TODO(lry): support static fields. (separate IR instruction?) 667 // TODO(lry): support static fields. (separate IR instruction?)
631 if (element.isField || element.isGetter) return giveup(); 668 if (element.isField || element.isGetter) return giveup();
632 // TODO(kmillikin): support static setters. 669 // TODO(kmillikin): support static setters.
633 if (element.isSetter) return giveup(); 670 if (element.isSetter) return giveup();
634 // TODO(lry): support constructors / factory calls. 671 // TODO(lry): support constructors / factory calls.
635 if (element.isConstructor) return giveup(); 672 if (element.isConstructor) return giveup();
636 // TODO(lry): support foreign functions. 673 // TODO(lry): support foreign functions.
637 if (element.isForeign(compiler)) return giveup(); 674 if (element.isForeign(compiler)) return giveup();
638 // TODO(lry): for elements that could not be resolved emit code to throw a 675 // TODO(lry): for elements that could not be resolved emit code to throw a
639 // [NoSuchMethodError]. 676 // [NoSuchMethodError].
640 if (element.isErroneous) return giveup(); 677 if (element.isErroneous) return giveup();
641 // TODO(lry): generate IR for object identicality. 678 // TODO(lry): generate IR for object identicality.
642 if (element == compiler.identicalFunction) giveup(); 679 if (element == compiler.identicalFunction) giveup();
643 680
644 Selector selector = elements.getSelector(node); 681 Selector selector = elements.getSelector(node);
645 // TODO(lry): support named arguments 682 // TODO(lry): support named arguments
646 if (selector.namedArgumentCount != 0) return giveup(); 683 if (selector.namedArgumentCount != 0) return giveup();
647 684
648 // TODO(kmillikin): support a receiver: A.m(). 685 // TODO(kmillikin): support a receiver: A.m().
649 if (node.receiver != null) return giveup(); 686 if (node.receiver != null) return giveup();
650 687
651 List arguments = [];
652 // TODO(lry): support default arguments, need support for locals. 688 // TODO(lry): support default arguments, need support for locals.
653 bool succeeded = selector.addArgumentsToList( 689 List<ir.Definition> arguments = node.arguments.toList(growable:false)
654 node.arguments, arguments, element.implementation, visit, 690 .map(visit).toList(growable:false);
655 (node) => giveup(), compiler);
656 if (!succeeded) {
657 // TODO(lry): generate code to throw a [WrongArgumentCountError].
658 return giveup();
659 }
660 ir.Parameter v = new ir.Parameter(null); 691 ir.Parameter v = new ir.Parameter(null);
661 ir.Continuation k = new ir.Continuation([v]); 692 ir.Continuation k = new ir.Continuation([v]);
662 ir.Expression invoke = 693 ir.Expression invoke =
663 new ir.InvokeStatic(element, selector, k, arguments); 694 new ir.InvokeStatic(element, selector, k, arguments);
664 add(new ir.LetCont(k, invoke)); 695 add(new ir.LetCont(k, invoke));
665 return v; 696 return v;
666 } 697 }
667 698
668 ir.Primitive visitSuperSend(ast.Send node) { 699 ir.Primitive visitSuperSend(ast.Send node) {
669 assert(isOpen); 700 assert(isOpen);
670 return giveup(); 701 return giveup();
671 } 702 }
672 703
673 ir.Primitive visitTypeReferenceSend(ast.Send node) { 704 ir.Primitive visitTypeReferenceSend(ast.Send node) {
674 assert(isOpen); 705 assert(isOpen);
675 return giveup(); 706 return giveup();
676 } 707 }
677 708
678 ir.Primitive visitSendSet(ast.SendSet node) { 709 ir.Primitive visitSendSet(ast.SendSet node) {
679 assert(isOpen); 710 assert(isOpen);
680 Element element = elements[node]; 711 Element element = elements[node];
681 if (!Elements.isLocal(element)) return giveup();
682 if (node.assignmentOperator.source != '=') return giveup(); 712 if (node.assignmentOperator.source != '=') return giveup();
683 // Exactly one argument expected for a simple assignment. 713 if (Elements.isLocal(element)) {
684 assert(!node.arguments.isEmpty); 714 // Exactly one argument expected for a simple assignment.
685 assert(node.arguments.tail.isEmpty); 715 assert(!node.arguments.isEmpty);
686 ir.Primitive result = visit(node.arguments.head); 716 assert(node.arguments.tail.isEmpty);
687 assignedVars[variableIndex[element]] = result; 717 ir.Primitive result = visit(node.arguments.head);
688 return result; 718 assignedVars[variableIndex[element]] = result;
719 return result;
720 } else if (Elements.isStaticOrTopLevel(element)) {
721 // TODO(asgerf): static and top-level
722 return giveup();
723 } else if (node.receiver == null) {
724 // Nodes that fall in this case:
725 // - Unresolved top-level
726 // - Assignment to final variable (will not be resolved)
727 return giveup();
728 } else {
729 // Setter or index-setter invocation
730 assert(node.receiver != null);
731 if (node.receiver.isSuper()) return giveup();
732
733 ir.Primitive receiver = visit(node.receiver);
734 ir.Parameter v = new ir.Parameter(null);
735 ir.Continuation k = new ir.Continuation([v]);
736 Selector selector = elements.getSelector(node);
737 assert(selector.kind == SelectorKind.SETTER ||
738 selector.kind == SelectorKind.INDEX);
739 List<ir.Definition> args = node.arguments.toList(growable:false)
740 .map(visit).toList(growable:false);
741 ir.InvokeMethod invoke = new ir.InvokeMethod(receiver, selector, k, args);
742 add(new ir.LetCont(k, invoke));
743 return args.last;
744 }
745 }
746
747 ir.Primitive visitNewExpression(ast.NewExpression node) {
748 if (node.isConst) {
749 return giveup(); // TODO(asgerf): Const constructor call.
750 }
751 FunctionElement element = elements[node.send];
752 if (Elements.isUnresolved(element)) {
753 return giveup();
754 }
755 ast.Node selector = node.send.selector;
756 GenericType type = elements.getType(node);
757 ir.Parameter v = new ir.Parameter(null);
758 ir.Continuation k = new ir.Continuation([v]);
759 List<ir.Definition> args = node.send.arguments.toList(growable:false)
760 .map(visit).toList(growable:false);
761 ir.InvokeConstructor invoke = new ir.InvokeConstructor(
762 type,
763 element,
764 k,
765 args);
766 add(new ir.LetCont(k, invoke));
767 return v;
689 } 768 }
690 769
691 static final String ABORT_IRNODE_BUILDER = "IrNode builder aborted"; 770 static final String ABORT_IRNODE_BUILDER = "IrNode builder aborted";
692 771
693 ir.Primitive giveup() => throw ABORT_IRNODE_BUILDER; 772 ir.Primitive giveup() => throw ABORT_IRNODE_BUILDER;
694 773
695 ir.FunctionDefinition nullIfGiveup(ir.FunctionDefinition action()) { 774 ir.FunctionDefinition nullIfGiveup(ir.FunctionDefinition action()) {
696 try { 775 try {
697 return action(); 776 return action();
698 } catch(e) { 777 } catch(e) {
(...skipping 12 matching lines...) Expand all
711 bool visit(DartType type, Null _) => type.accept(this, null); 790 bool visit(DartType type, Null _) => type.accept(this, null);
712 791
713 bool visitType(DartType type, Null _) => false; 792 bool visitType(DartType type, Null _) => false;
714 793
715 bool visitVoidType(VoidType type, Null _) => true; 794 bool visitVoidType(VoidType type, Null _) => true;
716 795
717 // Currently, InterfaceType and TypedefType are supported so long as they 796 // Currently, InterfaceType and TypedefType are supported so long as they
718 // do not have type parameters. They are subclasses of GenericType. 797 // do not have type parameters. They are subclasses of GenericType.
719 bool visitGenericType(GenericType type, Null _) => !type.isGeneric; 798 bool visitGenericType(GenericType type, Null _) => !type.isGeneric;
720 } 799 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698