| 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 library dart2js.ir_nodes; | 4 library dart2js.ir_nodes; |
| 5 | 5 |
| 6 import 'dart:collection'; | 6 import 'dart:collection'; |
| 7 import '../constants/values.dart' as values; | 7 import '../constants/values.dart' as values; |
| 8 import '../dart_types.dart' show DartType, InterfaceType, TypeVariableType; | 8 import '../dart_types.dart' show DartType, InterfaceType, TypeVariableType; |
| 9 import '../elements/elements.dart'; | 9 import '../elements/elements.dart'; |
| 10 import '../io/source_information.dart' show SourceInformation; | 10 import '../io/source_information.dart' show SourceInformation; |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 209 | 209 |
| 210 /// Use the given element as a hint for naming this primitive. | 210 /// Use the given element as a hint for naming this primitive. |
| 211 /// | 211 /// |
| 212 /// Has no effect if this primitive already has a non-null [element]. | 212 /// Has no effect if this primitive already has a non-null [element]. |
| 213 void useElementAsHint(Entity hint) { | 213 void useElementAsHint(Entity hint) { |
| 214 if (this.hint == null) { | 214 if (this.hint == null) { |
| 215 this.hint = hint; | 215 this.hint = hint; |
| 216 } | 216 } |
| 217 } | 217 } |
| 218 | 218 |
| 219 /// True if this primitive has a value that can be used by other expressions. |
| 220 bool get hasValue; |
| 221 |
| 219 /// True if the primitive can be removed, assuming it has no uses | 222 /// True if the primitive can be removed, assuming it has no uses |
| 220 /// (this getter does not check if there are any uses). | 223 /// (this getter does not check if there are any uses). |
| 221 /// | 224 /// |
| 222 /// False must be returned for primitives that may throw, diverge, or have | 225 /// False must be returned for primitives that may throw, diverge, or have |
| 223 /// observable side-effects. | 226 /// observable side-effects. |
| 224 bool get isSafeForElimination; | 227 bool get isSafeForElimination; |
| 225 | 228 |
| 226 /// True if time-of-evaluation is irrelevant for the given primitive, | 229 /// True if time-of-evaluation is irrelevant for the given primitive, |
| 227 /// assuming its inputs are the same values. | 230 /// assuming its inputs are the same values. |
| 228 bool get isSafeForReordering; | 231 bool get isSafeForReordering; |
| (...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 474 [this.sourceInformation]) | 477 [this.sourceInformation]) |
| 475 : arguments = _referenceList(args); | 478 : arguments = _referenceList(args); |
| 476 | 479 |
| 477 InvokeStatic.byReference(this.target, | 480 InvokeStatic.byReference(this.target, |
| 478 this.selector, | 481 this.selector, |
| 479 this.arguments, | 482 this.arguments, |
| 480 [this.sourceInformation]); | 483 [this.sourceInformation]); |
| 481 | 484 |
| 482 accept(Visitor visitor) => visitor.visitInvokeStatic(this); | 485 accept(Visitor visitor) => visitor.visitInvokeStatic(this); |
| 483 | 486 |
| 487 bool get hasValue => true; |
| 488 |
| 484 void setParentPointers() { | 489 void setParentPointers() { |
| 485 _setParentsOnList(arguments, this); | 490 _setParentsOnList(arguments, this); |
| 486 } | 491 } |
| 487 } | 492 } |
| 488 | 493 |
| 489 enum CallingConvention { | 494 enum CallingConvention { |
| 490 /// JS receiver is the Dart receiver, there are no extra arguments. | 495 /// JS receiver is the Dart receiver, there are no extra arguments. |
| 491 /// | 496 /// |
| 492 /// For example: `foo.bar$1(x)` | 497 /// For example: `foo.bar$1(x)` |
| 493 Normal, | 498 Normal, |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 549 this.arguments = _referenceList(arguments); | 554 this.arguments = _referenceList(arguments); |
| 550 | 555 |
| 551 InvokeMethod.byReference(this.receiver, | 556 InvokeMethod.byReference(this.receiver, |
| 552 this.selector, | 557 this.selector, |
| 553 this.mask, | 558 this.mask, |
| 554 this.arguments, | 559 this.arguments, |
| 555 this.sourceInformation); | 560 this.sourceInformation); |
| 556 | 561 |
| 557 accept(Visitor visitor) => visitor.visitInvokeMethod(this); | 562 accept(Visitor visitor) => visitor.visitInvokeMethod(this); |
| 558 | 563 |
| 564 bool get hasValue => true; |
| 565 |
| 559 void setParentPointers() { | 566 void setParentPointers() { |
| 560 receiver.parent = this; | 567 receiver.parent = this; |
| 561 _setParentsOnList(arguments, this); | 568 _setParentsOnList(arguments, this); |
| 562 } | 569 } |
| 563 } | 570 } |
| 564 | 571 |
| 565 /// Invoke [target] on [receiver], bypassing dispatch and override semantics. | 572 /// Invoke [target] on [receiver], bypassing dispatch and override semantics. |
| 566 /// | 573 /// |
| 567 /// That is, if [receiver] is an instance of a class that overrides [target] | 574 /// That is, if [receiver] is an instance of a class that overrides [target] |
| 568 /// with a different implementation, the overriding implementation is bypassed | 575 /// with a different implementation, the overriding implementation is bypassed |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 609 InvokeMethodDirectly(Primitive receiver, | 616 InvokeMethodDirectly(Primitive receiver, |
| 610 this.target, | 617 this.target, |
| 611 this.selector, | 618 this.selector, |
| 612 List<Primitive> arguments, | 619 List<Primitive> arguments, |
| 613 this.sourceInformation) | 620 this.sourceInformation) |
| 614 : this.receiver = new Reference<Primitive>(receiver), | 621 : this.receiver = new Reference<Primitive>(receiver), |
| 615 this.arguments = _referenceList(arguments); | 622 this.arguments = _referenceList(arguments); |
| 616 | 623 |
| 617 accept(Visitor visitor) => visitor.visitInvokeMethodDirectly(this); | 624 accept(Visitor visitor) => visitor.visitInvokeMethodDirectly(this); |
| 618 | 625 |
| 626 bool get hasValue => true; |
| 627 |
| 619 void setParentPointers() { | 628 void setParentPointers() { |
| 620 receiver.parent = this; | 629 receiver.parent = this; |
| 621 _setParentsOnList(arguments, this); | 630 _setParentsOnList(arguments, this); |
| 622 } | 631 } |
| 623 } | 632 } |
| 624 | 633 |
| 625 /// Non-const call to a constructor. | 634 /// Non-const call to a constructor. |
| 626 /// | 635 /// |
| 627 /// The [target] may be a generative constructor (forwarding or normal) | 636 /// The [target] may be a generative constructor (forwarding or normal) |
| 628 /// or a non-redirecting factory. | 637 /// or a non-redirecting factory. |
| (...skipping 25 matching lines...) Expand all Loading... |
| 654 InvokeConstructor(this.dartType, | 663 InvokeConstructor(this.dartType, |
| 655 this.target, | 664 this.target, |
| 656 this.selector, | 665 this.selector, |
| 657 List<Primitive> args, | 666 List<Primitive> args, |
| 658 this.sourceInformation, | 667 this.sourceInformation, |
| 659 {this.allocationSiteType}) | 668 {this.allocationSiteType}) |
| 660 : arguments = _referenceList(args); | 669 : arguments = _referenceList(args); |
| 661 | 670 |
| 662 accept(Visitor visitor) => visitor.visitInvokeConstructor(this); | 671 accept(Visitor visitor) => visitor.visitInvokeConstructor(this); |
| 663 | 672 |
| 673 bool get hasValue => true; |
| 674 |
| 664 void setParentPointers() { | 675 void setParentPointers() { |
| 665 _setParentsOnList(arguments, this); | 676 _setParentsOnList(arguments, this); |
| 666 } | 677 } |
| 667 } | 678 } |
| 668 | 679 |
| 669 /// An alias for [value] in a context where the value is known to satisfy | 680 /// An alias for [value] in a context where the value is known to satisfy |
| 670 /// [type]. | 681 /// [type]. |
| 671 /// | 682 /// |
| 672 /// Refinement nodes are inserted before the type propagator pass and removed | 683 /// Refinement nodes are inserted before the type propagator pass and removed |
| 673 /// afterwards, so as not to complicate passes that don't reason about types, | 684 /// afterwards, so as not to complicate passes that don't reason about types, |
| 674 /// but need to reason about value references being identical (i.e. referring | 685 /// but need to reason about value references being identical (i.e. referring |
| 675 /// to the same primitive). | 686 /// to the same primitive). |
| 676 class Refinement extends Primitive { | 687 class Refinement extends Primitive { |
| 677 Reference<Primitive> value; | 688 Reference<Primitive> value; |
| 678 final TypeMask refineType; | 689 final TypeMask refineType; |
| 679 | 690 |
| 680 Refinement(Primitive value, this.refineType) | 691 Refinement(Primitive value, this.refineType) |
| 681 : value = new Reference<Primitive>(value); | 692 : value = new Reference<Primitive>(value); |
| 682 | 693 |
| 694 bool get hasValue => true; |
| 683 bool get isSafeForElimination => true; | 695 bool get isSafeForElimination => true; |
| 684 bool get isSafeForReordering => false; | 696 bool get isSafeForReordering => false; |
| 685 | 697 |
| 686 accept(Visitor visitor) => visitor.visitRefinement(this); | 698 accept(Visitor visitor) => visitor.visitRefinement(this); |
| 687 | 699 |
| 688 Primitive get effectiveDefinition => value.definition.effectiveDefinition; | 700 Primitive get effectiveDefinition => value.definition.effectiveDefinition; |
| 689 | 701 |
| 690 void setParentPointers() { | 702 void setParentPointers() { |
| 691 value.parent = this; | 703 value.parent = this; |
| 692 } | 704 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 709 /// | 721 /// |
| 710 /// If [dartType] is a [TypeVariableType], this is a singleton list with the | 722 /// If [dartType] is a [TypeVariableType], this is a singleton list with the |
| 711 /// internal representation of the type held in that type variable. | 723 /// internal representation of the type held in that type variable. |
| 712 /// | 724 /// |
| 713 /// If [dartType] is a [FunctionType], this is a singleton list with the | 725 /// If [dartType] is a [FunctionType], this is a singleton list with the |
| 714 /// internal representation of that type, | 726 /// internal representation of that type, |
| 715 /// | 727 /// |
| 716 /// Otherwise the list is empty. | 728 /// Otherwise the list is empty. |
| 717 final List<Reference<Primitive>> typeArguments; | 729 final List<Reference<Primitive>> typeArguments; |
| 718 | 730 |
| 719 /// The Interceptor for [value]. May be `null` if the test can be done | |
| 720 /// without an interceptor. May be the same as [value] after self-interceptor | |
| 721 /// optimization. | |
| 722 // TODO(24523): Remove this field. | |
| 723 Reference<Primitive> interceptor; | |
| 724 | |
| 725 TypeTest(Primitive value, | 731 TypeTest(Primitive value, |
| 726 this.dartType, | 732 this.dartType, |
| 727 List<Primitive> typeArguments) | 733 List<Primitive> typeArguments) |
| 728 : this.value = new Reference<Primitive>(value), | 734 : this.value = new Reference<Primitive>(value), |
| 729 this.typeArguments = _referenceList(typeArguments); | 735 this.typeArguments = _referenceList(typeArguments); |
| 730 | 736 |
| 731 accept(Visitor visitor) => visitor.visitTypeTest(this); | 737 accept(Visitor visitor) => visitor.visitTypeTest(this); |
| 732 | 738 |
| 739 bool get hasValue => true; |
| 733 bool get isSafeForElimination => true; | 740 bool get isSafeForElimination => true; |
| 734 bool get isSafeForReordering => true; | 741 bool get isSafeForReordering => true; |
| 735 | 742 |
| 736 void setParentPointers() { | 743 void setParentPointers() { |
| 737 value.parent = this; | 744 value.parent = this; |
| 738 _setParentsOnList(typeArguments, this); | 745 _setParentsOnList(typeArguments, this); |
| 739 if (interceptor != null) interceptor.parent = this; | |
| 740 } | 746 } |
| 741 } | 747 } |
| 742 | 748 |
| 743 /// An "is" type test for a raw type, performed by testing a flag property. | 749 /// An "is" type test for a raw type, performed by testing a flag property. |
| 744 /// | 750 /// |
| 745 /// Returns `true` if [interceptor] is for [dartType]. | 751 /// Returns `true` if [interceptor] is for [dartType]. |
| 746 class TypeTestViaFlag extends Primitive { | 752 class TypeTestViaFlag extends Primitive { |
| 747 Reference<Primitive> interceptor; | 753 Reference<Primitive> interceptor; |
| 748 final DartType dartType; | 754 final DartType dartType; |
| 749 | 755 |
| 750 TypeTestViaFlag(Primitive interceptor, this.dartType) | 756 TypeTestViaFlag(Primitive interceptor, this.dartType) |
| 751 : this.interceptor = new Reference<Primitive>(interceptor); | 757 : this.interceptor = new Reference<Primitive>(interceptor); |
| 752 | 758 |
| 753 accept(Visitor visitor) => visitor.visitTypeTestViaFlag(this); | 759 accept(Visitor visitor) => visitor.visitTypeTestViaFlag(this); |
| 754 | 760 |
| 761 bool get hasValue => true; |
| 755 bool get isSafeForElimination => true; | 762 bool get isSafeForElimination => true; |
| 756 bool get isSafeForReordering => true; | 763 bool get isSafeForReordering => true; |
| 757 | 764 |
| 758 void setParentPointers() { | 765 void setParentPointers() { |
| 759 interceptor.parent = this; | 766 interceptor.parent = this; |
| 760 } | 767 } |
| 761 } | 768 } |
| 762 | 769 |
| 763 /// An "as" type cast. | 770 /// An "as" type cast. |
| 764 /// | 771 /// |
| (...skipping 13 matching lines...) Expand all Loading... |
| 778 final List<Reference<Primitive>> typeArguments; | 785 final List<Reference<Primitive>> typeArguments; |
| 779 | 786 |
| 780 TypeCast(Primitive value, | 787 TypeCast(Primitive value, |
| 781 this.dartType, | 788 this.dartType, |
| 782 List<Primitive> typeArguments) | 789 List<Primitive> typeArguments) |
| 783 : this.value = new Reference<Primitive>(value), | 790 : this.value = new Reference<Primitive>(value), |
| 784 this.typeArguments = _referenceList(typeArguments); | 791 this.typeArguments = _referenceList(typeArguments); |
| 785 | 792 |
| 786 accept(Visitor visitor) => visitor.visitTypeCast(this); | 793 accept(Visitor visitor) => visitor.visitTypeCast(this); |
| 787 | 794 |
| 795 bool get hasValue => true; |
| 796 |
| 788 void setParentPointers() { | 797 void setParentPointers() { |
| 789 value.parent = this; | 798 value.parent = this; |
| 790 _setParentsOnList(typeArguments, this); | 799 _setParentsOnList(typeArguments, this); |
| 791 } | 800 } |
| 792 } | 801 } |
| 793 | 802 |
| 794 /// Apply a built-in operator. | 803 /// Apply a built-in operator. |
| 795 /// | 804 /// |
| 796 /// It must be known that the arguments have the proper types. | 805 /// It must be known that the arguments have the proper types. |
| 797 class ApplyBuiltinOperator extends Primitive { | 806 class ApplyBuiltinOperator extends Primitive { |
| 798 BuiltinOperator operator; | 807 BuiltinOperator operator; |
| 799 List<Reference<Primitive>> arguments; | 808 List<Reference<Primitive>> arguments; |
| 800 final SourceInformation sourceInformation; | 809 final SourceInformation sourceInformation; |
| 801 | 810 |
| 802 ApplyBuiltinOperator(this.operator, | 811 ApplyBuiltinOperator(this.operator, |
| 803 List<Primitive> arguments, | 812 List<Primitive> arguments, |
| 804 this.sourceInformation) | 813 this.sourceInformation) |
| 805 : this.arguments = _referenceList(arguments); | 814 : this.arguments = _referenceList(arguments); |
| 806 | 815 |
| 807 accept(Visitor visitor) => visitor.visitApplyBuiltinOperator(this); | 816 accept(Visitor visitor) => visitor.visitApplyBuiltinOperator(this); |
| 808 | 817 |
| 818 bool get hasValue => true; |
| 809 bool get isSafeForElimination => true; | 819 bool get isSafeForElimination => true; |
| 810 bool get isSafeForReordering => true; | 820 bool get isSafeForReordering => true; |
| 811 | 821 |
| 812 void setParentPointers() { | 822 void setParentPointers() { |
| 813 _setParentsOnList(arguments, this); | 823 _setParentsOnList(arguments, this); |
| 814 } | 824 } |
| 815 } | 825 } |
| 816 | 826 |
| 817 /// Apply a built-in method. | 827 /// Apply a built-in method. |
| 818 /// | 828 /// |
| 819 /// It must be known that the arguments have the proper types. | 829 /// It must be known that the arguments have the proper types. |
| 820 class ApplyBuiltinMethod extends Primitive { | 830 class ApplyBuiltinMethod extends Primitive { |
| 821 BuiltinMethod method; | 831 BuiltinMethod method; |
| 822 Reference<Primitive> receiver; | 832 Reference<Primitive> receiver; |
| 823 List<Reference<Primitive>> arguments; | 833 List<Reference<Primitive>> arguments; |
| 824 final SourceInformation sourceInformation; | 834 final SourceInformation sourceInformation; |
| 825 | 835 |
| 826 bool receiverIsNotNull; | 836 bool receiverIsNotNull; |
| 827 | 837 |
| 828 ApplyBuiltinMethod(this.method, | 838 ApplyBuiltinMethod(this.method, |
| 829 Primitive receiver, | 839 Primitive receiver, |
| 830 List<Primitive> arguments, | 840 List<Primitive> arguments, |
| 831 this.sourceInformation, | 841 this.sourceInformation, |
| 832 {this.receiverIsNotNull: false}) | 842 {this.receiverIsNotNull: false}) |
| 833 : this.receiver = new Reference<Primitive>(receiver), | 843 : this.receiver = new Reference<Primitive>(receiver), |
| 834 this.arguments = _referenceList(arguments); | 844 this.arguments = _referenceList(arguments); |
| 835 | 845 |
| 836 accept(Visitor visitor) => visitor.visitApplyBuiltinMethod(this); | 846 accept(Visitor visitor) => visitor.visitApplyBuiltinMethod(this); |
| 837 | 847 |
| 848 bool get hasValue => true; |
| 838 bool get isSafeForElimination => false; | 849 bool get isSafeForElimination => false; |
| 839 bool get isSafeForReordering => false; | 850 bool get isSafeForReordering => false; |
| 840 | 851 |
| 841 void setParentPointers() { | 852 void setParentPointers() { |
| 842 receiver.parent = this; | 853 receiver.parent = this; |
| 843 _setParentsOnList(arguments, this); | 854 _setParentsOnList(arguments, this); |
| 844 } | 855 } |
| 845 } | 856 } |
| 846 | 857 |
| 847 /// Throw a value. | 858 /// Throw a value. |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 887 /// let prim p = ![variable] in [body] | 898 /// let prim p = ![variable] in [body] |
| 888 /// | 899 /// |
| 889 class GetMutable extends Primitive { | 900 class GetMutable extends Primitive { |
| 890 final Reference<MutableVariable> variable; | 901 final Reference<MutableVariable> variable; |
| 891 | 902 |
| 892 GetMutable(MutableVariable variable) | 903 GetMutable(MutableVariable variable) |
| 893 : this.variable = new Reference<MutableVariable>(variable); | 904 : this.variable = new Reference<MutableVariable>(variable); |
| 894 | 905 |
| 895 accept(Visitor visitor) => visitor.visitGetMutable(this); | 906 accept(Visitor visitor) => visitor.visitGetMutable(this); |
| 896 | 907 |
| 908 bool get hasValue => true; |
| 897 bool get isSafeForElimination => true; | 909 bool get isSafeForElimination => true; |
| 898 bool get isSafeForReordering => false; | 910 bool get isSafeForReordering => false; |
| 899 | 911 |
| 900 void setParentPointers() { | 912 void setParentPointers() { |
| 901 variable.parent = this; | 913 variable.parent = this; |
| 902 } | 914 } |
| 903 } | 915 } |
| 904 | 916 |
| 905 /// Assign a [MutableVariable]. | 917 /// Assign a [MutableVariable]. |
| 906 /// | 918 /// |
| 907 /// [MutableVariable]s can be seen as ref cells that are not first-class | 919 /// [MutableVariable]s can be seen as ref cells that are not first-class |
| 908 /// values. This can be seen as a dereferencing assignment: | 920 /// values. This can be seen as a dereferencing assignment: |
| 909 /// | 921 /// |
| 910 /// { [variable] := [value]; [body] } | 922 /// { [variable] := [value]; [body] } |
| 911 class SetMutable extends Primitive { | 923 class SetMutable extends Primitive { |
| 912 final Reference<MutableVariable> variable; | 924 final Reference<MutableVariable> variable; |
| 913 final Reference<Primitive> value; | 925 final Reference<Primitive> value; |
| 914 | 926 |
| 915 SetMutable(MutableVariable variable, Primitive value) | 927 SetMutable(MutableVariable variable, Primitive value) |
| 916 : this.variable = new Reference<MutableVariable>(variable), | 928 : this.variable = new Reference<MutableVariable>(variable), |
| 917 this.value = new Reference<Primitive>(value); | 929 this.value = new Reference<Primitive>(value); |
| 918 | 930 |
| 919 accept(Visitor visitor) => visitor.visitSetMutable(this); | 931 accept(Visitor visitor) => visitor.visitSetMutable(this); |
| 920 | 932 |
| 933 bool get hasValue => false; |
| 921 bool get isSafeForElimination => false; | 934 bool get isSafeForElimination => false; |
| 922 bool get isSafeForReordering => false; | 935 bool get isSafeForReordering => false; |
| 923 | 936 |
| 924 void setParentPointers() { | 937 void setParentPointers() { |
| 925 variable.parent = this; | 938 variable.parent = this; |
| 926 value.parent = this; | 939 value.parent = this; |
| 927 } | 940 } |
| 928 } | 941 } |
| 929 | 942 |
| 930 /// Invoke a continuation in tail position. | 943 /// Invoke a continuation in tail position. |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1015 final Reference<Primitive> object; | 1028 final Reference<Primitive> object; |
| 1016 FieldElement field; | 1029 FieldElement field; |
| 1017 final Reference<Primitive> value; | 1030 final Reference<Primitive> value; |
| 1018 | 1031 |
| 1019 SetField(Primitive object, this.field, Primitive value) | 1032 SetField(Primitive object, this.field, Primitive value) |
| 1020 : this.object = new Reference<Primitive>(object), | 1033 : this.object = new Reference<Primitive>(object), |
| 1021 this.value = new Reference<Primitive>(value); | 1034 this.value = new Reference<Primitive>(value); |
| 1022 | 1035 |
| 1023 accept(Visitor visitor) => visitor.visitSetField(this); | 1036 accept(Visitor visitor) => visitor.visitSetField(this); |
| 1024 | 1037 |
| 1038 bool get hasValue => false; |
| 1025 bool get isSafeForElimination => false; | 1039 bool get isSafeForElimination => false; |
| 1026 bool get isSafeForReordering => false; | 1040 bool get isSafeForReordering => false; |
| 1027 | 1041 |
| 1028 void setParentPointers() { | 1042 void setParentPointers() { |
| 1029 object.parent = this; | 1043 object.parent = this; |
| 1030 value.parent = this; | 1044 value.parent = this; |
| 1031 } | 1045 } |
| 1032 } | 1046 } |
| 1033 | 1047 |
| 1034 /// Directly reads from a field on a given object. | 1048 /// Directly reads from a field on a given object. |
| 1035 /// | 1049 /// |
| 1036 /// The [object] must either be `null` or an object that has [field]. | 1050 /// The [object] must either be `null` or an object that has [field]. |
| 1037 class GetField extends Primitive { | 1051 class GetField extends Primitive { |
| 1038 final Reference<Primitive> object; | 1052 final Reference<Primitive> object; |
| 1039 FieldElement field; | 1053 FieldElement field; |
| 1040 | 1054 |
| 1041 /// True if the object is known not to be null. | 1055 /// True if the object is known not to be null. |
| 1042 // TODO(asgerf): This is a placeholder until we agree on how to track | 1056 // TODO(asgerf): This is a placeholder until we agree on how to track |
| 1043 // side effects. | 1057 // side effects. |
| 1044 bool objectIsNotNull = false; | 1058 bool objectIsNotNull = false; |
| 1045 | 1059 |
| 1046 GetField(Primitive object, this.field) | 1060 GetField(Primitive object, this.field) |
| 1047 : this.object = new Reference<Primitive>(object); | 1061 : this.object = new Reference<Primitive>(object); |
| 1048 | 1062 |
| 1049 accept(Visitor visitor) => visitor.visitGetField(this); | 1063 accept(Visitor visitor) => visitor.visitGetField(this); |
| 1050 | 1064 |
| 1065 bool get hasValue => true; |
| 1051 bool get isSafeForElimination => objectIsNotNull; | 1066 bool get isSafeForElimination => objectIsNotNull; |
| 1052 bool get isSafeForReordering => false; | 1067 bool get isSafeForReordering => false; |
| 1053 | 1068 |
| 1054 toString() => 'GetField($field)'; | 1069 toString() => 'GetField($field)'; |
| 1055 | 1070 |
| 1056 void setParentPointers() { | 1071 void setParentPointers() { |
| 1057 object.parent = this; | 1072 object.parent = this; |
| 1058 } | 1073 } |
| 1059 } | 1074 } |
| 1060 | 1075 |
| 1061 /// Get the length of a string or native list. | 1076 /// Get the length of a string or native list. |
| 1062 class GetLength extends Primitive { | 1077 class GetLength extends Primitive { |
| 1063 final Reference<Primitive> object; | 1078 final Reference<Primitive> object; |
| 1064 | 1079 |
| 1065 /// True if the object is known not to be null. | 1080 /// True if the object is known not to be null. |
| 1066 bool objectIsNotNull = false; | 1081 bool objectIsNotNull = false; |
| 1067 | 1082 |
| 1068 GetLength(Primitive object) : this.object = new Reference<Primitive>(object); | 1083 GetLength(Primitive object) : this.object = new Reference<Primitive>(object); |
| 1069 | 1084 |
| 1085 bool get hasValue => true; |
| 1070 bool get isSafeForElimination => objectIsNotNull; | 1086 bool get isSafeForElimination => objectIsNotNull; |
| 1071 bool get isSafeForReordering => false; | 1087 bool get isSafeForReordering => false; |
| 1072 | 1088 |
| 1073 accept(Visitor v) => v.visitGetLength(this); | 1089 accept(Visitor v) => v.visitGetLength(this); |
| 1074 | 1090 |
| 1075 void setParentPointers() { | 1091 void setParentPointers() { |
| 1076 object.parent = this; | 1092 object.parent = this; |
| 1077 } | 1093 } |
| 1078 } | 1094 } |
| 1079 | 1095 |
| 1080 /// Read an entry from a string or native list. | 1096 /// Read an entry from a string or native list. |
| 1081 /// | 1097 /// |
| 1082 /// [object] must be null or a native list or a string, and [index] must be | 1098 /// [object] must be null or a native list or a string, and [index] must be |
| 1083 /// an integer. | 1099 /// an integer. |
| 1084 class GetIndex extends Primitive { | 1100 class GetIndex extends Primitive { |
| 1085 final Reference<Primitive> object; | 1101 final Reference<Primitive> object; |
| 1086 final Reference<Primitive> index; | 1102 final Reference<Primitive> index; |
| 1087 | 1103 |
| 1088 /// True if the object is known not to be null. | 1104 /// True if the object is known not to be null. |
| 1089 bool objectIsNotNull = false; | 1105 bool objectIsNotNull = false; |
| 1090 | 1106 |
| 1091 GetIndex(Primitive object, Primitive index) | 1107 GetIndex(Primitive object, Primitive index) |
| 1092 : this.object = new Reference<Primitive>(object), | 1108 : this.object = new Reference<Primitive>(object), |
| 1093 this.index = new Reference<Primitive>(index); | 1109 this.index = new Reference<Primitive>(index); |
| 1094 | 1110 |
| 1111 bool get hasValue => true; |
| 1095 bool get isSafeForElimination => objectIsNotNull; | 1112 bool get isSafeForElimination => objectIsNotNull; |
| 1096 bool get isSafeForReordering => false; | 1113 bool get isSafeForReordering => false; |
| 1097 | 1114 |
| 1098 accept(Visitor v) => v.visitGetIndex(this); | 1115 accept(Visitor v) => v.visitGetIndex(this); |
| 1099 | 1116 |
| 1100 void setParentPointers() { | 1117 void setParentPointers() { |
| 1101 object.parent = this; | 1118 object.parent = this; |
| 1102 index.parent = this; | 1119 index.parent = this; |
| 1103 } | 1120 } |
| 1104 } | 1121 } |
| 1105 | 1122 |
| 1106 /// Set an entry on a native list. | 1123 /// Set an entry on a native list. |
| 1107 /// | 1124 /// |
| 1108 /// [object] must be null or a native list, and [index] must be an integer. | 1125 /// [object] must be null or a native list, and [index] must be an integer. |
| 1109 /// | 1126 /// |
| 1110 /// The primitive itself has no value and may not be referenced. | 1127 /// The primitive itself has no value and may not be referenced. |
| 1111 class SetIndex extends Primitive { | 1128 class SetIndex extends Primitive { |
| 1112 final Reference<Primitive> object; | 1129 final Reference<Primitive> object; |
| 1113 final Reference<Primitive> index; | 1130 final Reference<Primitive> index; |
| 1114 final Reference<Primitive> value; | 1131 final Reference<Primitive> value; |
| 1115 | 1132 |
| 1116 SetIndex(Primitive object, Primitive index, Primitive value) | 1133 SetIndex(Primitive object, Primitive index, Primitive value) |
| 1117 : this.object = new Reference<Primitive>(object), | 1134 : this.object = new Reference<Primitive>(object), |
| 1118 this.index = new Reference<Primitive>(index), | 1135 this.index = new Reference<Primitive>(index), |
| 1119 this.value = new Reference<Primitive>(value); | 1136 this.value = new Reference<Primitive>(value); |
| 1120 | 1137 |
| 1138 bool get hasValue => false; |
| 1121 bool get isSafeForElimination => false; | 1139 bool get isSafeForElimination => false; |
| 1122 bool get isSafeForReordering => false; | 1140 bool get isSafeForReordering => false; |
| 1123 | 1141 |
| 1124 accept(Visitor v) => v.visitSetIndex(this); | 1142 accept(Visitor v) => v.visitSetIndex(this); |
| 1125 | 1143 |
| 1126 void setParentPointers() { | 1144 void setParentPointers() { |
| 1127 object.parent = this; | 1145 object.parent = this; |
| 1128 index.parent = this; | 1146 index.parent = this; |
| 1129 value.parent = this; | 1147 value.parent = this; |
| 1130 } | 1148 } |
| 1131 } | 1149 } |
| 1132 | 1150 |
| 1133 /// Reads the value of a static field or tears off a static method. | 1151 /// Reads the value of a static field or tears off a static method. |
| 1134 /// | 1152 /// |
| 1135 /// Note that lazily initialized fields should be read using GetLazyStatic. | 1153 /// Note that lazily initialized fields should be read using GetLazyStatic. |
| 1136 class GetStatic extends Primitive { | 1154 class GetStatic extends Primitive { |
| 1137 /// Can be [FieldElement] or [FunctionElement]. | 1155 /// Can be [FieldElement] or [FunctionElement]. |
| 1138 final Element element; | 1156 final Element element; |
| 1139 final SourceInformation sourceInformation; | 1157 final SourceInformation sourceInformation; |
| 1140 | 1158 |
| 1141 GetStatic(this.element, [this.sourceInformation]); | 1159 GetStatic(this.element, [this.sourceInformation]); |
| 1142 | 1160 |
| 1143 accept(Visitor visitor) => visitor.visitGetStatic(this); | 1161 accept(Visitor visitor) => visitor.visitGetStatic(this); |
| 1144 | 1162 |
| 1145 bool get isSafeForElimination { | 1163 bool get hasValue => true; |
| 1146 return true; | 1164 bool get isSafeForElimination => true; |
| 1147 } | |
| 1148 bool get isSafeForReordering { | 1165 bool get isSafeForReordering { |
| 1149 return element is FunctionElement || element.isFinal; | 1166 return element is FunctionElement || element.isFinal; |
| 1150 } | 1167 } |
| 1151 | 1168 |
| 1152 void setParentPointers() {} | 1169 void setParentPointers() {} |
| 1153 } | 1170 } |
| 1154 | 1171 |
| 1155 /// Sets the value of a static field. | 1172 /// Sets the value of a static field. |
| 1156 class SetStatic extends Primitive { | 1173 class SetStatic extends Primitive { |
| 1157 final FieldElement element; | 1174 final FieldElement element; |
| 1158 final Reference<Primitive> value; | 1175 final Reference<Primitive> value; |
| 1159 final SourceInformation sourceInformation; | 1176 final SourceInformation sourceInformation; |
| 1160 | 1177 |
| 1161 SetStatic(this.element, Primitive value, [this.sourceInformation]) | 1178 SetStatic(this.element, Primitive value, [this.sourceInformation]) |
| 1162 : this.value = new Reference<Primitive>(value); | 1179 : this.value = new Reference<Primitive>(value); |
| 1163 | 1180 |
| 1164 accept(Visitor visitor) => visitor.visitSetStatic(this); | 1181 accept(Visitor visitor) => visitor.visitSetStatic(this); |
| 1165 | 1182 |
| 1183 bool get hasValue => false; |
| 1166 bool get isSafeForElimination => false; | 1184 bool get isSafeForElimination => false; |
| 1167 bool get isSafeForReordering => false; | 1185 bool get isSafeForReordering => false; |
| 1168 | 1186 |
| 1169 void setParentPointers() { | 1187 void setParentPointers() { |
| 1170 value.parent = this; | 1188 value.parent = this; |
| 1171 } | 1189 } |
| 1172 } | 1190 } |
| 1173 | 1191 |
| 1174 /// Reads the value of a lazily initialized static field. | 1192 /// Reads the value of a lazily initialized static field. |
| 1175 /// | 1193 /// |
| 1176 /// If the field has not yet been initialized, its initializer is evaluated | 1194 /// If the field has not yet been initialized, its initializer is evaluated |
| 1177 /// and assigned to the field. | 1195 /// and assigned to the field. |
| 1178 class GetLazyStatic extends UnsafePrimitive { | 1196 class GetLazyStatic extends UnsafePrimitive { |
| 1179 final FieldElement element; | 1197 final FieldElement element; |
| 1180 final SourceInformation sourceInformation; | 1198 final SourceInformation sourceInformation; |
| 1181 | 1199 |
| 1182 GetLazyStatic(this.element, [this.sourceInformation]); | 1200 GetLazyStatic(this.element, [this.sourceInformation]); |
| 1183 | 1201 |
| 1184 accept(Visitor visitor) => visitor.visitGetLazyStatic(this); | 1202 accept(Visitor visitor) => visitor.visitGetLazyStatic(this); |
| 1185 | 1203 |
| 1186 void setParentPointers() { | 1204 bool get hasValue => true; |
| 1187 } | 1205 |
| 1206 void setParentPointers() {} |
| 1188 } | 1207 } |
| 1189 | 1208 |
| 1190 /// Creates an object for holding boxed variables captured by a closure. | 1209 /// Creates an object for holding boxed variables captured by a closure. |
| 1191 class CreateBox extends Primitive { | 1210 class CreateBox extends Primitive { |
| 1192 accept(Visitor visitor) => visitor.visitCreateBox(this); | 1211 accept(Visitor visitor) => visitor.visitCreateBox(this); |
| 1193 | 1212 |
| 1213 bool get hasValue => true; |
| 1194 bool get isSafeForElimination => true; | 1214 bool get isSafeForElimination => true; |
| 1195 bool get isSafeForReordering => true; | 1215 bool get isSafeForReordering => true; |
| 1196 | 1216 |
| 1197 void setParentPointers() {} | 1217 void setParentPointers() {} |
| 1198 } | 1218 } |
| 1199 | 1219 |
| 1200 /// Creates an instance of a class and initializes its fields and runtime type | 1220 /// Creates an instance of a class and initializes its fields and runtime type |
| 1201 /// information. | 1221 /// information. |
| 1202 class CreateInstance extends Primitive { | 1222 class CreateInstance extends Primitive { |
| 1203 final ClassElement classElement; | 1223 final ClassElement classElement; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1216 final SourceInformation sourceInformation; | 1236 final SourceInformation sourceInformation; |
| 1217 | 1237 |
| 1218 CreateInstance(this.classElement, List<Primitive> arguments, | 1238 CreateInstance(this.classElement, List<Primitive> arguments, |
| 1219 List<Primitive> typeInformation, | 1239 List<Primitive> typeInformation, |
| 1220 this.sourceInformation) | 1240 this.sourceInformation) |
| 1221 : this.arguments = _referenceList(arguments), | 1241 : this.arguments = _referenceList(arguments), |
| 1222 this.typeInformation = _referenceList(typeInformation); | 1242 this.typeInformation = _referenceList(typeInformation); |
| 1223 | 1243 |
| 1224 accept(Visitor visitor) => visitor.visitCreateInstance(this); | 1244 accept(Visitor visitor) => visitor.visitCreateInstance(this); |
| 1225 | 1245 |
| 1246 bool get hasValue => true; |
| 1226 bool get isSafeForElimination => true; | 1247 bool get isSafeForElimination => true; |
| 1227 bool get isSafeForReordering => true; | 1248 bool get isSafeForReordering => true; |
| 1228 | 1249 |
| 1229 toString() => 'CreateInstance($classElement)'; | 1250 toString() => 'CreateInstance($classElement)'; |
| 1230 | 1251 |
| 1231 void setParentPointers() { | 1252 void setParentPointers() { |
| 1232 _setParentsOnList(arguments, this); | 1253 _setParentsOnList(arguments, this); |
| 1233 if (typeInformation != null) _setParentsOnList(typeInformation, this); | 1254 if (typeInformation != null) _setParentsOnList(typeInformation, this); |
| 1234 } | 1255 } |
| 1235 } | 1256 } |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1312 /// [interceptedClasses]. | 1333 /// [interceptedClasses]. |
| 1313 bool get isInterceptedClassAlwaysExact { | 1334 bool get isInterceptedClassAlwaysExact { |
| 1314 return flags & (INTERCEPT & ~INTERCEPT_EXACT) == 0; | 1335 return flags & (INTERCEPT & ~INTERCEPT_EXACT) == 0; |
| 1315 } | 1336 } |
| 1316 | 1337 |
| 1317 Interceptor(Primitive input, this.sourceInformation) | 1338 Interceptor(Primitive input, this.sourceInformation) |
| 1318 : this.input = new Reference<Primitive>(input); | 1339 : this.input = new Reference<Primitive>(input); |
| 1319 | 1340 |
| 1320 accept(Visitor visitor) => visitor.visitInterceptor(this); | 1341 accept(Visitor visitor) => visitor.visitInterceptor(this); |
| 1321 | 1342 |
| 1343 bool get hasValue => true; |
| 1322 bool get isSafeForElimination => true; | 1344 bool get isSafeForElimination => true; |
| 1323 bool get isSafeForReordering => true; | 1345 bool get isSafeForReordering => true; |
| 1324 | 1346 |
| 1325 void setParentPointers() { | 1347 void setParentPointers() { |
| 1326 input.parent = this; | 1348 input.parent = this; |
| 1327 } | 1349 } |
| 1328 } | 1350 } |
| 1329 | 1351 |
| 1330 /// Create an instance of [Invocation] for use in a call to `noSuchMethod`. | 1352 /// Create an instance of [Invocation] for use in a call to `noSuchMethod`. |
| 1331 class CreateInvocationMirror extends Primitive { | 1353 class CreateInvocationMirror extends Primitive { |
| 1332 final Selector selector; | 1354 final Selector selector; |
| 1333 final List<Reference<Primitive>> arguments; | 1355 final List<Reference<Primitive>> arguments; |
| 1334 | 1356 |
| 1335 CreateInvocationMirror(this.selector, List<Primitive> arguments) | 1357 CreateInvocationMirror(this.selector, List<Primitive> arguments) |
| 1336 : this.arguments = _referenceList(arguments); | 1358 : this.arguments = _referenceList(arguments); |
| 1337 | 1359 |
| 1338 accept(Visitor visitor) => visitor.visitCreateInvocationMirror(this); | 1360 accept(Visitor visitor) => visitor.visitCreateInvocationMirror(this); |
| 1339 | 1361 |
| 1362 bool get hasValue => true; |
| 1340 bool get isSafeForElimination => true; | 1363 bool get isSafeForElimination => true; |
| 1341 bool get isSafeForReordering => true; | 1364 bool get isSafeForReordering => true; |
| 1342 | 1365 |
| 1343 void setParentPointers() { | 1366 void setParentPointers() { |
| 1344 _setParentsOnList(arguments, this); | 1367 _setParentsOnList(arguments, this); |
| 1345 } | 1368 } |
| 1346 } | 1369 } |
| 1347 | 1370 |
| 1348 class ForeignCode extends UnsafePrimitive { | 1371 class ForeignCode extends UnsafePrimitive { |
| 1349 final js.Template codeTemplate; | 1372 final js.Template codeTemplate; |
| 1350 final TypeMask type; | 1373 final TypeMask type; |
| 1351 final List<Reference<Primitive>> arguments; | 1374 final List<Reference<Primitive>> arguments; |
| 1352 final native.NativeBehavior nativeBehavior; | 1375 final native.NativeBehavior nativeBehavior; |
| 1353 final FunctionElement dependency; | 1376 final FunctionElement dependency; |
| 1354 | 1377 |
| 1355 ForeignCode(this.codeTemplate, this.type, List<Primitive> arguments, | 1378 ForeignCode(this.codeTemplate, this.type, List<Primitive> arguments, |
| 1356 this.nativeBehavior, {this.dependency}) | 1379 this.nativeBehavior, {this.dependency}) |
| 1357 : this.arguments = _referenceList(arguments); | 1380 : this.arguments = _referenceList(arguments); |
| 1358 | 1381 |
| 1359 accept(Visitor visitor) => visitor.visitForeignCode(this); | 1382 accept(Visitor visitor) => visitor.visitForeignCode(this); |
| 1360 | 1383 |
| 1384 bool get hasValue => true; |
| 1385 |
| 1361 void setParentPointers() { | 1386 void setParentPointers() { |
| 1362 _setParentsOnList(arguments, this); | 1387 _setParentsOnList(arguments, this); |
| 1363 } | 1388 } |
| 1364 } | 1389 } |
| 1365 | 1390 |
| 1366 class Constant extends Primitive { | 1391 class Constant extends Primitive { |
| 1367 final values.ConstantValue value; | 1392 final values.ConstantValue value; |
| 1368 final SourceInformation sourceInformation; | 1393 final SourceInformation sourceInformation; |
| 1369 | 1394 |
| 1370 Constant(this.value, {this.sourceInformation}) { | 1395 Constant(this.value, {this.sourceInformation}) { |
| 1371 assert(value != null); | 1396 assert(value != null); |
| 1372 } | 1397 } |
| 1373 | 1398 |
| 1374 accept(Visitor visitor) => visitor.visitConstant(this); | 1399 accept(Visitor visitor) => visitor.visitConstant(this); |
| 1375 | 1400 |
| 1401 bool get hasValue => true; |
| 1376 bool get isSafeForElimination => true; | 1402 bool get isSafeForElimination => true; |
| 1377 bool get isSafeForReordering => true; | 1403 bool get isSafeForReordering => true; |
| 1378 | 1404 |
| 1379 void setParentPointers() {} | 1405 void setParentPointers() {} |
| 1380 } | 1406 } |
| 1381 | 1407 |
| 1382 class LiteralList extends Primitive { | 1408 class LiteralList extends Primitive { |
| 1383 /// The List type being created; this is not the type argument. | 1409 /// The List type being created; this is not the type argument. |
| 1384 final InterfaceType dartType; | 1410 final InterfaceType dartType; |
| 1385 final List<Reference<Primitive>> values; | 1411 final List<Reference<Primitive>> values; |
| 1386 | 1412 |
| 1387 /// If non-null, this is an allocation site-specific type for the list | 1413 /// If non-null, this is an allocation site-specific type for the list |
| 1388 /// created here. | 1414 /// created here. |
| 1389 TypeMask allocationSiteType; | 1415 TypeMask allocationSiteType; |
| 1390 | 1416 |
| 1391 LiteralList(this.dartType, List<Primitive> values, {this.allocationSiteType}) | 1417 LiteralList(this.dartType, List<Primitive> values, {this.allocationSiteType}) |
| 1392 : this.values = _referenceList(values); | 1418 : this.values = _referenceList(values); |
| 1393 | 1419 |
| 1394 accept(Visitor visitor) => visitor.visitLiteralList(this); | 1420 accept(Visitor visitor) => visitor.visitLiteralList(this); |
| 1395 | 1421 |
| 1422 bool get hasValue => true; |
| 1396 bool get isSafeForElimination => true; | 1423 bool get isSafeForElimination => true; |
| 1397 bool get isSafeForReordering => true; | 1424 bool get isSafeForReordering => true; |
| 1398 | 1425 |
| 1399 void setParentPointers() { | 1426 void setParentPointers() { |
| 1400 _setParentsOnList(values, this); | 1427 _setParentsOnList(values, this); |
| 1401 } | 1428 } |
| 1402 } | 1429 } |
| 1403 | 1430 |
| 1404 class LiteralMapEntry { | 1431 class LiteralMapEntry { |
| 1405 final Reference<Primitive> key; | 1432 final Reference<Primitive> key; |
| 1406 final Reference<Primitive> value; | 1433 final Reference<Primitive> value; |
| 1407 | 1434 |
| 1408 LiteralMapEntry(Primitive key, Primitive value) | 1435 LiteralMapEntry(Primitive key, Primitive value) |
| 1409 : this.key = new Reference<Primitive>(key), | 1436 : this.key = new Reference<Primitive>(key), |
| 1410 this.value = new Reference<Primitive>(value); | 1437 this.value = new Reference<Primitive>(value); |
| 1411 } | 1438 } |
| 1412 | 1439 |
| 1413 class LiteralMap extends Primitive { | 1440 class LiteralMap extends Primitive { |
| 1414 final InterfaceType dartType; | 1441 final InterfaceType dartType; |
| 1415 final List<LiteralMapEntry> entries; | 1442 final List<LiteralMapEntry> entries; |
| 1416 | 1443 |
| 1417 LiteralMap(this.dartType, this.entries); | 1444 LiteralMap(this.dartType, this.entries); |
| 1418 | 1445 |
| 1419 accept(Visitor visitor) => visitor.visitLiteralMap(this); | 1446 accept(Visitor visitor) => visitor.visitLiteralMap(this); |
| 1420 | 1447 |
| 1448 bool get hasValue => true; |
| 1421 bool get isSafeForElimination => true; | 1449 bool get isSafeForElimination => true; |
| 1422 bool get isSafeForReordering => true; | 1450 bool get isSafeForReordering => true; |
| 1423 | 1451 |
| 1424 void setParentPointers() { | 1452 void setParentPointers() { |
| 1425 for (LiteralMapEntry entry in entries) { | 1453 for (LiteralMapEntry entry in entries) { |
| 1426 entry.key.parent = this; | 1454 entry.key.parent = this; |
| 1427 entry.value.parent = this; | 1455 entry.value.parent = this; |
| 1428 } | 1456 } |
| 1429 } | 1457 } |
| 1430 } | 1458 } |
| 1431 | 1459 |
| 1432 /// Currently unused. | |
| 1433 /// | |
| 1434 /// Nested functions (from Dart code) are translated to classes by closure | |
| 1435 /// conversion, hence they are instantiated with [CreateInstance]. | |
| 1436 /// | |
| 1437 /// We keep this around for now because it might come in handy when we | |
| 1438 /// handle async/await in the CPS IR. | |
| 1439 /// | |
| 1440 /// Instantiates a nested function. [MutableVariable]s are in scope in the | |
| 1441 /// inner function, but primitives are not shared across function boundaries. | |
| 1442 class CreateFunction extends Primitive { | |
| 1443 final FunctionDefinition definition; | |
| 1444 | |
| 1445 CreateFunction(this.definition); | |
| 1446 | |
| 1447 accept(Visitor visitor) => visitor.visitCreateFunction(this); | |
| 1448 | |
| 1449 bool get isSafeForElimination => true; | |
| 1450 bool get isSafeForReordering => true; | |
| 1451 | |
| 1452 void setParentPointers() {} | |
| 1453 } | |
| 1454 | |
| 1455 class Parameter extends Primitive { | 1460 class Parameter extends Primitive { |
| 1456 Parameter(Entity hint) { | 1461 Parameter(Entity hint) { |
| 1457 super.hint = hint; | 1462 super.hint = hint; |
| 1458 } | 1463 } |
| 1459 | 1464 |
| 1460 accept(Visitor visitor) => visitor.visitParameter(this); | 1465 accept(Visitor visitor) => visitor.visitParameter(this); |
| 1461 | 1466 |
| 1462 String toString() => 'Parameter(${hint == null ? null : hint.name})'; | 1467 String toString() => 'Parameter(${hint == null ? null : hint.name})'; |
| 1463 | 1468 |
| 1469 bool get hasValue => true; |
| 1464 bool get isSafeForElimination => true; | 1470 bool get isSafeForElimination => true; |
| 1465 bool get isSafeForReordering => true; | 1471 bool get isSafeForReordering => true; |
| 1466 | 1472 |
| 1467 void setParentPointers() {} | 1473 void setParentPointers() {} |
| 1468 } | 1474 } |
| 1469 | 1475 |
| 1470 /// Continuations are normally bound by 'let cont'. A continuation with one | 1476 /// Continuations are normally bound by 'let cont'. A continuation with one |
| 1471 /// parameter and no body is used to represent a function's return continuation. | 1477 /// parameter and no body is used to represent a function's return continuation. |
| 1472 /// The return continuation is bound by the function, not by 'let cont'. | 1478 /// The return continuation is bound by the function, not by 'let cont'. |
| 1473 class Continuation extends Definition<Continuation> implements InteriorNode { | 1479 class Continuation extends Definition<Continuation> implements InteriorNode { |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1547 final Reference<Primitive> value; | 1553 final Reference<Primitive> value; |
| 1548 | 1554 |
| 1549 final SourceInformation sourceInformation; | 1555 final SourceInformation sourceInformation; |
| 1550 | 1556 |
| 1551 ReifyRuntimeType(Primitive value, this.sourceInformation) | 1557 ReifyRuntimeType(Primitive value, this.sourceInformation) |
| 1552 : this.value = new Reference<Primitive>(value); | 1558 : this.value = new Reference<Primitive>(value); |
| 1553 | 1559 |
| 1554 @override | 1560 @override |
| 1555 accept(Visitor visitor) => visitor.visitReifyRuntimeType(this); | 1561 accept(Visitor visitor) => visitor.visitReifyRuntimeType(this); |
| 1556 | 1562 |
| 1563 bool get hasValue => true; |
| 1557 bool get isSafeForElimination => true; | 1564 bool get isSafeForElimination => true; |
| 1558 bool get isSafeForReordering => true; | 1565 bool get isSafeForReordering => true; |
| 1559 | 1566 |
| 1560 void setParentPointers() { | 1567 void setParentPointers() { |
| 1561 value.parent = this; | 1568 value.parent = this; |
| 1562 } | 1569 } |
| 1563 } | 1570 } |
| 1564 | 1571 |
| 1565 /// Read the value the type variable [variable] from the target object. | 1572 /// Read the value the type variable [variable] from the target object. |
| 1566 /// | 1573 /// |
| 1567 /// The resulting value is an internal representation (and not neccessarily a | 1574 /// The resulting value is an internal representation (and not neccessarily a |
| 1568 /// Dart object), and must be reified by [ReifyRuntimeType], if it should be | 1575 /// Dart object), and must be reified by [ReifyRuntimeType], if it should be |
| 1569 /// used as a Dart value. | 1576 /// used as a Dart value. |
| 1570 class ReadTypeVariable extends Primitive { | 1577 class ReadTypeVariable extends Primitive { |
| 1571 final TypeVariableType variable; | 1578 final TypeVariableType variable; |
| 1572 final Reference<Primitive> target; | 1579 final Reference<Primitive> target; |
| 1573 final SourceInformation sourceInformation; | 1580 final SourceInformation sourceInformation; |
| 1574 | 1581 |
| 1575 ReadTypeVariable(this.variable, Primitive target, this.sourceInformation) | 1582 ReadTypeVariable(this.variable, Primitive target, this.sourceInformation) |
| 1576 : this.target = new Reference<Primitive>(target); | 1583 : this.target = new Reference<Primitive>(target); |
| 1577 | 1584 |
| 1578 @override | 1585 @override |
| 1579 accept(Visitor visitor) => visitor.visitReadTypeVariable(this); | 1586 accept(Visitor visitor) => visitor.visitReadTypeVariable(this); |
| 1580 | 1587 |
| 1588 bool get hasValue => true; |
| 1581 bool get isSafeForElimination => true; | 1589 bool get isSafeForElimination => true; |
| 1582 bool get isSafeForReordering => true; | 1590 bool get isSafeForReordering => true; |
| 1583 | 1591 |
| 1584 void setParentPointers() { | 1592 void setParentPointers() { |
| 1585 target.parent = this; | 1593 target.parent = this; |
| 1586 } | 1594 } |
| 1587 } | 1595 } |
| 1588 | 1596 |
| 1589 /// Representation of a closed type (that is, a type without type variables). | 1597 /// Representation of a closed type (that is, a type without type variables). |
| 1590 /// | 1598 /// |
| 1591 /// The resulting value is constructed from [dartType] by replacing the type | 1599 /// The resulting value is constructed from [dartType] by replacing the type |
| 1592 /// variables with consecutive values from [arguments], in the order generated | 1600 /// variables with consecutive values from [arguments], in the order generated |
| 1593 /// by [DartType.forEachTypeVariable]. The type variables in [dartType] are | 1601 /// by [DartType.forEachTypeVariable]. The type variables in [dartType] are |
| 1594 /// treated as 'holes' in the term, which means that it must be ensured at | 1602 /// treated as 'holes' in the term, which means that it must be ensured at |
| 1595 /// construction, that duplicate occurences of a type variable in [dartType] | 1603 /// construction, that duplicate occurences of a type variable in [dartType] |
| 1596 /// are assigned the same value. | 1604 /// are assigned the same value. |
| 1597 class TypeExpression extends Primitive { | 1605 class TypeExpression extends Primitive { |
| 1598 final DartType dartType; | 1606 final DartType dartType; |
| 1599 final List<Reference<Primitive>> arguments; | 1607 final List<Reference<Primitive>> arguments; |
| 1600 | 1608 |
| 1601 TypeExpression(this.dartType, | 1609 TypeExpression(this.dartType, |
| 1602 [List<Primitive> arguments = const <Primitive>[]]) | 1610 [List<Primitive> arguments = const <Primitive>[]]) |
| 1603 : this.arguments = _referenceList(arguments); | 1611 : this.arguments = _referenceList(arguments); |
| 1604 | 1612 |
| 1605 @override | 1613 @override |
| 1606 accept(Visitor visitor) { | 1614 accept(Visitor visitor) { |
| 1607 return visitor.visitTypeExpression(this); | 1615 return visitor.visitTypeExpression(this); |
| 1608 } | 1616 } |
| 1609 | 1617 |
| 1618 bool get hasValue => true; |
| 1610 bool get isSafeForElimination => true; | 1619 bool get isSafeForElimination => true; |
| 1611 bool get isSafeForReordering => true; | 1620 bool get isSafeForReordering => true; |
| 1612 | 1621 |
| 1613 void setParentPointers() { | 1622 void setParentPointers() { |
| 1614 _setParentsOnList(arguments, this); | 1623 _setParentsOnList(arguments, this); |
| 1615 } | 1624 } |
| 1616 } | 1625 } |
| 1617 | 1626 |
| 1618 class Await extends UnsafePrimitive { | 1627 class Await extends UnsafePrimitive { |
| 1619 final Reference<Primitive> input; | 1628 final Reference<Primitive> input; |
| 1620 | 1629 |
| 1621 Await(Primitive input) | 1630 Await(Primitive input) |
| 1622 : this.input = new Reference<Primitive>(input); | 1631 : this.input = new Reference<Primitive>(input); |
| 1623 | 1632 |
| 1624 @override | 1633 @override |
| 1625 accept(Visitor visitor) { | 1634 accept(Visitor visitor) { |
| 1626 return visitor.visitAwait(this); | 1635 return visitor.visitAwait(this); |
| 1627 } | 1636 } |
| 1628 | 1637 |
| 1638 bool get hasValue => true; |
| 1639 |
| 1629 void setParentPointers() { | 1640 void setParentPointers() { |
| 1630 input.parent = this; | 1641 input.parent = this; |
| 1631 } | 1642 } |
| 1632 } | 1643 } |
| 1633 | 1644 |
| 1634 class Yield extends UnsafePrimitive { | 1645 class Yield extends UnsafePrimitive { |
| 1635 final Reference<Primitive> input; | 1646 final Reference<Primitive> input; |
| 1636 final bool hasStar; | 1647 final bool hasStar; |
| 1637 | 1648 |
| 1638 Yield(Primitive input, this.hasStar) | 1649 Yield(Primitive input, this.hasStar) |
| 1639 : this.input = new Reference<Primitive>(input); | 1650 : this.input = new Reference<Primitive>(input); |
| 1640 | 1651 |
| 1641 @override | 1652 @override |
| 1642 accept(Visitor visitor) { | 1653 accept(Visitor visitor) { |
| 1643 return visitor.visitYield(this); | 1654 return visitor.visitYield(this); |
| 1644 } | 1655 } |
| 1645 | 1656 |
| 1657 bool get hasValue => true; |
| 1658 |
| 1646 void setParentPointers() { | 1659 void setParentPointers() { |
| 1647 input.parent = this; | 1660 input.parent = this; |
| 1648 } | 1661 } |
| 1649 } | 1662 } |
| 1650 | 1663 |
| 1651 List<Reference<Primitive>> _referenceList(Iterable<Primitive> definitions) { | 1664 List<Reference<Primitive>> _referenceList(Iterable<Primitive> definitions) { |
| 1652 return definitions.map((e) => new Reference<Primitive>(e)).toList(); | 1665 return definitions.map((e) => new Reference<Primitive>(e)).toList(); |
| 1653 } | 1666 } |
| 1654 | 1667 |
| 1655 void _setParentsOnNodes(List<Node> nodes, Node parent) { | 1668 void _setParentsOnNodes(List<Node> nodes, Node parent) { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1691 T visitGetLazyStatic(GetLazyStatic node); | 1704 T visitGetLazyStatic(GetLazyStatic node); |
| 1692 T visitSetField(SetField node); | 1705 T visitSetField(SetField node); |
| 1693 T visitUnreachable(Unreachable node); | 1706 T visitUnreachable(Unreachable node); |
| 1694 T visitAwait(Await node); | 1707 T visitAwait(Await node); |
| 1695 T visitYield(Yield node); | 1708 T visitYield(Yield node); |
| 1696 | 1709 |
| 1697 // Definitions. | 1710 // Definitions. |
| 1698 T visitLiteralList(LiteralList node); | 1711 T visitLiteralList(LiteralList node); |
| 1699 T visitLiteralMap(LiteralMap node); | 1712 T visitLiteralMap(LiteralMap node); |
| 1700 T visitConstant(Constant node); | 1713 T visitConstant(Constant node); |
| 1701 T visitCreateFunction(CreateFunction node); | |
| 1702 T visitGetMutable(GetMutable node); | 1714 T visitGetMutable(GetMutable node); |
| 1703 T visitParameter(Parameter node); | 1715 T visitParameter(Parameter node); |
| 1704 T visitContinuation(Continuation node); | 1716 T visitContinuation(Continuation node); |
| 1705 T visitMutableVariable(MutableVariable node); | 1717 T visitMutableVariable(MutableVariable node); |
| 1706 T visitGetStatic(GetStatic node); | 1718 T visitGetStatic(GetStatic node); |
| 1707 T visitInterceptor(Interceptor node); | 1719 T visitInterceptor(Interceptor node); |
| 1708 T visitCreateInstance(CreateInstance node); | 1720 T visitCreateInstance(CreateInstance node); |
| 1709 T visitGetField(GetField node); | 1721 T visitGetField(GetField node); |
| 1710 T visitCreateBox(CreateBox node); | 1722 T visitCreateBox(CreateBox node); |
| 1711 T visitReifyRuntimeType(ReifyRuntimeType node); | 1723 T visitReifyRuntimeType(ReifyRuntimeType node); |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1846 visitTypeCast(TypeCast node) { | 1858 visitTypeCast(TypeCast node) { |
| 1847 processTypeCast(node); | 1859 processTypeCast(node); |
| 1848 processReference(node.value); | 1860 processReference(node.value); |
| 1849 node.typeArguments.forEach(processReference); | 1861 node.typeArguments.forEach(processReference); |
| 1850 } | 1862 } |
| 1851 | 1863 |
| 1852 processTypeTest(TypeTest node) {} | 1864 processTypeTest(TypeTest node) {} |
| 1853 visitTypeTest(TypeTest node) { | 1865 visitTypeTest(TypeTest node) { |
| 1854 processTypeTest(node); | 1866 processTypeTest(node); |
| 1855 processReference(node.value); | 1867 processReference(node.value); |
| 1856 if (node.interceptor != null) processReference(node.interceptor); | |
| 1857 node.typeArguments.forEach(processReference); | 1868 node.typeArguments.forEach(processReference); |
| 1858 } | 1869 } |
| 1859 | 1870 |
| 1860 processTypeTestViaFlag(TypeTestViaFlag node) {} | 1871 processTypeTestViaFlag(TypeTestViaFlag node) {} |
| 1861 visitTypeTestViaFlag(TypeTestViaFlag node) { | 1872 visitTypeTestViaFlag(TypeTestViaFlag node) { |
| 1862 processTypeTestViaFlag(node); | 1873 processTypeTestViaFlag(node); |
| 1863 processReference(node.interceptor); | 1874 processReference(node.interceptor); |
| 1864 } | 1875 } |
| 1865 | 1876 |
| 1866 processSetMutable(SetMutable node) {} | 1877 processSetMutable(SetMutable node) {} |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1888 processReference(entry.key); | 1899 processReference(entry.key); |
| 1889 processReference(entry.value); | 1900 processReference(entry.value); |
| 1890 } | 1901 } |
| 1891 } | 1902 } |
| 1892 | 1903 |
| 1893 processConstant(Constant node) {} | 1904 processConstant(Constant node) {} |
| 1894 visitConstant(Constant node) { | 1905 visitConstant(Constant node) { |
| 1895 processConstant(node); | 1906 processConstant(node); |
| 1896 } | 1907 } |
| 1897 | 1908 |
| 1898 processCreateFunction(CreateFunction node) {} | |
| 1899 visitCreateFunction(CreateFunction node) { | |
| 1900 processCreateFunction(node); | |
| 1901 visit(node.definition); | |
| 1902 } | |
| 1903 | |
| 1904 processMutableVariable(node) {} | 1909 processMutableVariable(node) {} |
| 1905 visitMutableVariable(MutableVariable node) { | 1910 visitMutableVariable(MutableVariable node) { |
| 1906 processMutableVariable(node); | 1911 processMutableVariable(node); |
| 1907 } | 1912 } |
| 1908 | 1913 |
| 1909 processGetMutable(GetMutable node) {} | 1914 processGetMutable(GetMutable node) {} |
| 1910 visitGetMutable(GetMutable node) { | 1915 visitGetMutable(GetMutable node) { |
| 1911 processGetMutable(node); | 1916 processGetMutable(node); |
| 1912 processReference(node.variable); | 1917 processReference(node.variable); |
| 1913 } | 1918 } |
| (...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2171 /// Visit a just-deleted subterm and unlink all [Reference]s in it. | 2176 /// Visit a just-deleted subterm and unlink all [Reference]s in it. |
| 2172 class RemovalVisitor extends TrampolineRecursiveVisitor { | 2177 class RemovalVisitor extends TrampolineRecursiveVisitor { |
| 2173 processReference(Reference reference) { | 2178 processReference(Reference reference) { |
| 2174 reference.unlink(); | 2179 reference.unlink(); |
| 2175 } | 2180 } |
| 2176 | 2181 |
| 2177 static void remove(Node node) { | 2182 static void remove(Node node) { |
| 2178 (new RemovalVisitor()).visit(node); | 2183 (new RemovalVisitor()).visit(node); |
| 2179 } | 2184 } |
| 2180 } | 2185 } |
| OLD | NEW |