OLD | NEW |
---|---|
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 // IrNodes are kept in a separate library to have precise control over their | 5 // IrNodes are kept in a separate library to have precise control over their |
6 // dependencies on other parts of the system. | 6 // dependencies on other parts of the system. |
7 library dart2js.ir_nodes; | 7 library dart2js.ir_nodes; |
8 | 8 |
9 import '../constants/expressions.dart'; | 9 import '../constants/expressions.dart'; |
10 import '../constants/values.dart' as values show ConstantValue; | 10 import '../constants/values.dart' as values show ConstantValue; |
11 import '../dart2jslib.dart' as dart2js show invariant; | 11 import '../dart2jslib.dart' as dart2js show invariant; |
12 import '../elements/elements.dart'; | 12 import '../elements/elements.dart'; |
13 import '../universe/universe.dart' show Selector, SelectorKind; | 13 import '../universe/universe.dart' show Selector, SelectorKind; |
14 import '../dart_types.dart' show DartType, GenericType; | 14 import '../dart_types.dart' show DartType, GenericType; |
15 import '../cps_ir/optimizers.dart'; | |
15 | 16 |
16 abstract class Node { | 17 abstract class Node { |
17 static int hashCount = 0; | 18 static int hashCount = 0; |
18 final int hashCode = hashCount = (hashCount + 1) & 0x3fffffff; | 19 final int hashCode = hashCount = (hashCount + 1) & 0x3fffffff; |
19 | 20 |
20 /// A pointer to the parent node. Is null until set by optimization passes. | 21 /// A pointer to the parent node. Is null until set by optimization passes. |
21 Node parent; | 22 Node parent; |
22 | 23 |
23 accept(Visitor visitor); | 24 accept(Visitor visitor); |
24 } | 25 } |
(...skipping 512 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
537 | 538 |
538 bool get isReturnContinuation => body == null; | 539 bool get isReturnContinuation => body == null; |
539 | 540 |
540 Continuation(this.parameters); | 541 Continuation(this.parameters); |
541 | 542 |
542 Continuation.retrn() : parameters = <Parameter>[new Parameter(null)]; | 543 Continuation.retrn() : parameters = <Parameter>[new Parameter(null)]; |
543 | 544 |
544 accept(Visitor visitor) => visitor.visitContinuation(this); | 545 accept(Visitor visitor) => visitor.visitContinuation(this); |
545 } | 546 } |
546 | 547 |
548 abstract class ExecutableDefinition implements Node { | |
549 acceptPass(Pass pass); | |
550 } | |
551 | |
552 // This is basically a function definition with an empty parameter list and a | |
553 // field element instead of a function element and no const declarations, and | |
554 // never a getter or setter, though that's less important. | |
555 class FieldDefinition extends Node | |
Kevin Millikin (Google)
2014/11/26 13:31:30
Better:
class FieldDefinition extends Node
im
sigurdm
2014/11/26 14:38:43
Done.
| |
556 implements InteriorNode, ExecutableDefinition { | |
557 final FieldElement element; | |
558 final Continuation returnContinuation; | |
559 Expression body; | |
560 | |
561 FieldDefinition(this.element, this.returnContinuation, this.body); | |
562 accept(Visitor visitor) => visitor.visitFieldDefinition(this); | |
563 acceptPass(Pass pass) => pass.rewriteFieldDefinition(this); | |
564 } | |
565 | |
547 /// A function definition, consisting of parameters and a body. The parameters | 566 /// A function definition, consisting of parameters and a body. The parameters |
548 /// include a distinguished continuation parameter. | 567 /// include a distinguished continuation parameter. |
549 class FunctionDefinition extends Node implements InteriorNode { | 568 class FunctionDefinition extends Node implements InteriorNode, |
569 ExecutableDefinition { | |
550 final FunctionElement element; | 570 final FunctionElement element; |
551 final Continuation returnContinuation; | 571 final Continuation returnContinuation; |
552 final List<Parameter> parameters; | 572 final List<Parameter> parameters; |
553 Expression body; | 573 Expression body; |
554 final List<ConstDeclaration> localConstants; | 574 final List<ConstDeclaration> localConstants; |
555 | 575 |
556 /// Values for optional parameters. | 576 /// Values for optional parameters. |
557 final List<ConstantExpression> defaultParameterValues; | 577 final List<ConstantExpression> defaultParameterValues; |
558 | 578 |
559 FunctionDefinition(this.element, this.returnContinuation, | 579 FunctionDefinition(this.element, this.returnContinuation, |
560 this.parameters, this.body, this.localConstants, | 580 this.parameters, this.body, this.localConstants, |
561 this.defaultParameterValues); | 581 this.defaultParameterValues); |
562 | 582 |
563 FunctionDefinition.abstract(this.element, | 583 FunctionDefinition.abstract(this.element, |
564 this.parameters, | 584 this.parameters, |
565 this.defaultParameterValues) | 585 this.defaultParameterValues) |
566 : this.returnContinuation = null, | 586 : this.returnContinuation = null, |
567 this.localConstants = const <ConstDeclaration>[]; | 587 this.localConstants = const <ConstDeclaration>[]; |
568 | 588 |
569 accept(Visitor visitor) => visitor.visitFunctionDefinition(this); | 589 accept(Visitor visitor) => visitor.visitFunctionDefinition(this); |
590 acceptPass(Pass pass) => pass.rewriteFunctionDefinition(this); | |
Kevin Millikin (Google)
2014/11/26 13:31:29
applyPass?
sigurdm
2014/11/26 14:38:43
Done.
| |
570 | 591 |
571 /// Returns `true` if this function is abstract or external. | 592 /// Returns `true` if this function is abstract or external. |
572 /// | 593 /// |
573 /// If `true`, [body] and [returnContinuation] are `null` and [localConstants] | 594 /// If `true`, [body] and [returnContinuation] are `null` and [localConstants] |
574 /// is empty. | 595 /// is empty. |
575 bool get isAbstract => body == null; | 596 bool get isAbstract => body == null; |
576 } | 597 } |
577 | 598 |
578 List<Reference<Primitive>> _referenceList(Iterable<Primitive> definitions) { | 599 List<Reference<Primitive>> _referenceList(Iterable<Primitive> definitions) { |
579 return definitions.map((e) => new Reference<Primitive>(e)).toList(); | 600 return definitions.map((e) => new Reference<Primitive>(e)).toList(); |
580 } | 601 } |
581 | 602 |
582 abstract class Visitor<T> { | 603 abstract class Visitor<T> { |
583 const Visitor(); | 604 const Visitor(); |
584 | 605 |
585 T visit(Node node) => node.accept(this); | 606 T visit(Node node) => node.accept(this); |
586 // Abstract classes. | 607 // Abstract classes. |
587 T visitNode(Node node) => null; | 608 T visitNode(Node node) => null; |
588 T visitExpression(Expression node) => visitNode(node); | 609 T visitExpression(Expression node) => visitNode(node); |
589 T visitDefinition(Definition node) => visitNode(node); | 610 T visitDefinition(Definition node) => visitNode(node); |
590 T visitPrimitive(Primitive node) => visitDefinition(node); | 611 T visitPrimitive(Primitive node) => visitDefinition(node); |
591 T visitCondition(Condition node) => visitNode(node); | 612 T visitCondition(Condition node) => visitNode(node); |
592 | 613 |
593 // Concrete classes. | 614 // Concrete classes. |
615 T visitFieldDefinition(FieldDefinition node) => visitNode(node); | |
594 T visitFunctionDefinition(FunctionDefinition node) => visitNode(node); | 616 T visitFunctionDefinition(FunctionDefinition node) => visitNode(node); |
595 | 617 |
596 // Expressions. | 618 // Expressions. |
597 T visitLetPrim(LetPrim node) => visitExpression(node); | 619 T visitLetPrim(LetPrim node) => visitExpression(node); |
598 T visitLetCont(LetCont node) => visitExpression(node); | 620 T visitLetCont(LetCont node) => visitExpression(node); |
599 T visitInvokeStatic(InvokeStatic node) => visitExpression(node); | 621 T visitInvokeStatic(InvokeStatic node) => visitExpression(node); |
600 T visitInvokeContinuation(InvokeContinuation node) => visitExpression(node); | 622 T visitInvokeContinuation(InvokeContinuation node) => visitExpression(node); |
601 T visitInvokeMethod(InvokeMethod node) => visitExpression(node); | 623 T visitInvokeMethod(InvokeMethod node) => visitExpression(node); |
602 T visitInvokeSuperMethod(InvokeSuperMethod node) => visitExpression(node); | 624 T visitInvokeSuperMethod(InvokeSuperMethod node) => visitExpression(node); |
603 T visitInvokeConstructor(InvokeConstructor node) => visitExpression(node); | 625 T visitInvokeConstructor(InvokeConstructor node) => visitExpression(node); |
(...skipping 26 matching lines...) Expand all Loading... | |
630 // Ensures that RecursiveVisitor contains overrides for all relevant nodes. | 652 // Ensures that RecursiveVisitor contains overrides for all relevant nodes. |
631 // As a rule of thumb, nodes with structure to traverse should be overridden | 653 // As a rule of thumb, nodes with structure to traverse should be overridden |
632 // with the appropriate visits in this class (for example, visitLetCont), | 654 // with the appropriate visits in this class (for example, visitLetCont), |
633 // while leaving other nodes for subclasses (i.e., visitLiteralList). | 655 // while leaving other nodes for subclasses (i.e., visitLiteralList). |
634 visitNode(Node node) { | 656 visitNode(Node node) { |
635 throw "RecursiveVisitor is stale, add missing visit overrides"; | 657 throw "RecursiveVisitor is stale, add missing visit overrides"; |
636 } | 658 } |
637 | 659 |
638 processReference(Reference ref) {} | 660 processReference(Reference ref) {} |
639 | 661 |
662 processFieldDefinition(FieldDefinition node) {} | |
663 visitFieldDefinition(FieldDefinition node) { | |
664 processFieldDefinition(node); | |
665 visit(node.body); | |
666 } | |
667 | |
640 processFunctionDefinition(FunctionDefinition node) {} | 668 processFunctionDefinition(FunctionDefinition node) {} |
641 visitFunctionDefinition(FunctionDefinition node) { | 669 visitFunctionDefinition(FunctionDefinition node) { |
642 processFunctionDefinition(node); | 670 processFunctionDefinition(node); |
643 node.parameters.forEach(visitParameter); | 671 node.parameters.forEach(visitParameter); |
644 visit(node.body); | 672 visit(node.body); |
645 } | 673 } |
646 | 674 |
647 // Expressions. | 675 // Expressions. |
648 | 676 |
649 processLetPrim(LetPrim node) {} | 677 processLetPrim(LetPrim node) {} |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
696 node.arguments.forEach(processReference); | 724 node.arguments.forEach(processReference); |
697 } | 725 } |
698 | 726 |
699 processConcatenateStrings(ConcatenateStrings node) {} | 727 processConcatenateStrings(ConcatenateStrings node) {} |
700 visitConcatenateStrings(ConcatenateStrings node) { | 728 visitConcatenateStrings(ConcatenateStrings node) { |
701 processConcatenateStrings(node); | 729 processConcatenateStrings(node); |
702 processReference(node.continuation); | 730 processReference(node.continuation); |
703 node.arguments.forEach(processReference); | 731 node.arguments.forEach(processReference); |
704 } | 732 } |
705 | 733 |
706 | |
707 processBranch(Branch node) {} | 734 processBranch(Branch node) {} |
708 visitBranch(Branch node) { | 735 visitBranch(Branch node) { |
709 processBranch(node); | 736 processBranch(node); |
710 processReference(node.trueContinuation); | 737 processReference(node.trueContinuation); |
711 processReference(node.falseContinuation); | 738 processReference(node.falseContinuation); |
712 visit(node.condition); | 739 visit(node.condition); |
713 } | 740 } |
714 | 741 |
715 processTypeOperator(TypeOperator node) {} | 742 processTypeOperator(TypeOperator node) {} |
716 visitTypeOperator(TypeOperator node) { | 743 visitTypeOperator(TypeOperator node) { |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
839 if (primitive.hint == null) return; | 866 if (primitive.hint == null) return; |
840 if (primitive.registerIndex != null) { | 867 if (primitive.registerIndex != null) { |
841 getRegisterArray(primitive.hint).releaseIndex(primitive.registerIndex); | 868 getRegisterArray(primitive.hint).releaseIndex(primitive.registerIndex); |
842 } | 869 } |
843 } | 870 } |
844 | 871 |
845 void visitReference(Reference reference) { | 872 void visitReference(Reference reference) { |
846 allocate(reference.definition); | 873 allocate(reference.definition); |
847 } | 874 } |
848 | 875 |
876 void visitFieldDefinition(FieldDefinition node) { | |
877 visit(node.body); | |
878 } | |
879 | |
849 void visitFunctionDefinition(FunctionDefinition node) { | 880 void visitFunctionDefinition(FunctionDefinition node) { |
850 if (!node.isAbstract) { | 881 if (!node.isAbstract) { |
851 visit(node.body); | 882 visit(node.body); |
852 } | 883 } |
853 node.parameters.forEach(allocate); // Assign indices to unused parameters. | 884 node.parameters.forEach(allocate); // Assign indices to unused parameters. |
854 elementRegisters.clear(); | |
855 } | 885 } |
856 | 886 |
857 void visitLetPrim(LetPrim node) { | 887 void visitLetPrim(LetPrim node) { |
858 visit(node.body); | 888 visit(node.body); |
859 release(node.primitive); | 889 release(node.primitive); |
860 visit(node.primitive); | 890 visit(node.primitive); |
861 } | 891 } |
862 | 892 |
863 void visitLetCont(LetCont node) { | 893 void visitLetCont(LetCont node) { |
864 visit(node.continuation); | 894 visit(node.continuation); |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
949 release(node.parameters[i]); | 979 release(node.parameters[i]); |
950 } | 980 } |
951 } | 981 } |
952 | 982 |
953 void visitIsTrue(IsTrue node) { | 983 void visitIsTrue(IsTrue node) { |
954 visitReference(node.value); | 984 visitReference(node.value); |
955 } | 985 } |
956 | 986 |
957 } | 987 } |
958 | 988 |
OLD | NEW |