Chromium Code Reviews| 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 |