Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 interface HVisitor<R> { | 5 interface HVisitor<R> { |
| 6 R visitAdd(HAdd node); | 6 R visitAdd(HAdd node); |
| 7 R visitBitAnd(HBitAnd node); | 7 R visitBitAnd(HBitAnd node); |
| 8 R visitBitNot(HBitNot node); | 8 R visitBitNot(HBitNot node); |
| 9 R visitBitOr(HBitOr node); | 9 R visitBitOr(HBitOr node); |
| 10 R visitBitXor(HBitXor node); | 10 R visitBitXor(HBitXor node); |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 147 return result; | 147 return result; |
| 148 } | 148 } |
| 149 | 149 |
| 150 static HType mapConstantTypeToSsaType(Constant constant) { | 150 static HType mapConstantTypeToSsaType(Constant constant) { |
| 151 if (constant.isNull()) return HType.UNKNOWN; | 151 if (constant.isNull()) return HType.UNKNOWN; |
| 152 if (constant.isBool()) return HType.BOOLEAN; | 152 if (constant.isBool()) return HType.BOOLEAN; |
| 153 if (constant.isInt()) return HType.INTEGER; | 153 if (constant.isInt()) return HType.INTEGER; |
| 154 if (constant.isDouble()) return HType.DOUBLE; | 154 if (constant.isDouble()) return HType.DOUBLE; |
| 155 if (constant.isString()) return HType.STRING; | 155 if (constant.isString()) return HType.STRING; |
| 156 if (constant.isList()) return HType.READABLE_ARRAY; | 156 if (constant.isList()) return HType.READABLE_ARRAY; |
| 157 if (constant.isMap()) { | |
| 158 MapConstant map = constant; | |
| 159 return new HNonPrimitiveType(map.type); | |
| 160 } | |
| 157 return HType.UNKNOWN; | 161 return HType.UNKNOWN; |
| 158 } | 162 } |
| 159 | 163 |
| 160 HConstant addConstant(Constant constant) { | 164 HConstant addConstant(Constant constant) { |
| 161 HConstant result = constants[constant]; | 165 HConstant result = constants[constant]; |
| 162 if (result === null) { | 166 if (result === null) { |
| 163 HType type = mapConstantTypeToSsaType(constant); | 167 HType type = mapConstantTypeToSsaType(constant); |
| 164 result = new HConstant.internal(constant, type); | 168 result = new HConstant.internal(constant, type); |
| 165 entry.addAtExit(result); | 169 entry.addAtExit(result); |
| 166 constants[constant] = result; | 170 constants[constant] = result; |
| (...skipping 496 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 663 | 667 |
| 664 static final int FLAG_CONFLICTING = 0; | 668 static final int FLAG_CONFLICTING = 0; |
| 665 static final int FLAG_UNKNOWN = 1; | 669 static final int FLAG_UNKNOWN = 1; |
| 666 static final int FLAG_BOOLEAN = FLAG_UNKNOWN << 1; | 670 static final int FLAG_BOOLEAN = FLAG_UNKNOWN << 1; |
| 667 static final int FLAG_INTEGER = FLAG_BOOLEAN << 1; | 671 static final int FLAG_INTEGER = FLAG_BOOLEAN << 1; |
| 668 static final int FLAG_STRING = FLAG_INTEGER << 1; | 672 static final int FLAG_STRING = FLAG_INTEGER << 1; |
| 669 static final int FLAG_READABLE_ARRAY = FLAG_STRING << 1; | 673 static final int FLAG_READABLE_ARRAY = FLAG_STRING << 1; |
| 670 // FLAG_WRITABLE_ARRAY implies FLAG_READABLE_ARRAY. | 674 // FLAG_WRITABLE_ARRAY implies FLAG_READABLE_ARRAY. |
| 671 static final int FLAG_WRITEABLE_ARRAY = FLAG_READABLE_ARRAY << 1; | 675 static final int FLAG_WRITEABLE_ARRAY = FLAG_READABLE_ARRAY << 1; |
| 672 static final int FLAG_DOUBLE = FLAG_WRITEABLE_ARRAY << 1; | 676 static final int FLAG_DOUBLE = FLAG_WRITEABLE_ARRAY << 1; |
| 677 static final int FLAG_NON_PRIMITIVE = FLAG_DOUBLE << 1; | |
| 673 | 678 |
| 674 static final HType CONFLICTING = const HType(FLAG_CONFLICTING); | 679 static final HType CONFLICTING = const HType(FLAG_CONFLICTING); |
| 675 static final HType UNKNOWN = const HType(FLAG_UNKNOWN); | 680 static final HType UNKNOWN = const HType(FLAG_UNKNOWN); |
| 676 static final HType BOOLEAN = const HType(FLAG_BOOLEAN); | 681 static final HType BOOLEAN = const HType(FLAG_BOOLEAN); |
| 677 static final HType STRING = const HType(FLAG_STRING); | 682 static final HType STRING = const HType(FLAG_STRING); |
| 678 static final HType READABLE_ARRAY = const HType(FLAG_READABLE_ARRAY); | 683 static final HType READABLE_ARRAY = const HType(FLAG_READABLE_ARRAY); |
| 679 static final HType MUTABLE_ARRAY = | 684 static final HType MUTABLE_ARRAY = |
| 680 const HType(FLAG_READABLE_ARRAY | FLAG_WRITEABLE_ARRAY); | 685 const HType(FLAG_READABLE_ARRAY | FLAG_WRITEABLE_ARRAY); |
| 681 static final HType INTEGER = const HType(FLAG_INTEGER); | 686 static final HType INTEGER = const HType(FLAG_INTEGER); |
| 682 static final HType DOUBLE = const HType(FLAG_DOUBLE); | 687 static final HType DOUBLE = const HType(FLAG_DOUBLE); |
| 683 static final HType STRING_OR_ARRAY = | 688 static final HType STRING_OR_ARRAY = |
| 684 const HType(FLAG_STRING | FLAG_READABLE_ARRAY | FLAG_WRITEABLE_ARRAY); | 689 const HType(FLAG_STRING | FLAG_READABLE_ARRAY | FLAG_WRITEABLE_ARRAY); |
| 685 static final HType NUMBER = const HType(FLAG_DOUBLE | FLAG_INTEGER); | 690 static final HType NUMBER = const HType(FLAG_DOUBLE | FLAG_INTEGER); |
| 686 | 691 |
| 687 bool isConflicting() => this === CONFLICTING; | 692 bool isConflicting() => this === CONFLICTING; |
| 688 bool isUnknown() => this === UNKNOWN; | 693 bool isUnknown() => this === UNKNOWN; |
| 689 bool isBoolean() => this === BOOLEAN; | 694 bool isBoolean() => this === BOOLEAN; |
| 690 bool isInteger() => this === INTEGER; | 695 bool isInteger() => this === INTEGER; |
| 691 bool isDouble() => this === DOUBLE; | 696 bool isDouble() => this === DOUBLE; |
| 692 bool isString() => this === STRING; | 697 bool isString() => this === STRING; |
| 693 bool isArray() => (this.flag & FLAG_READABLE_ARRAY) != 0; | 698 bool isArray() => (this.flag & FLAG_READABLE_ARRAY) != 0; |
| 694 bool isMutableArray() => this === MUTABLE_ARRAY; | 699 bool isMutableArray() => this === MUTABLE_ARRAY; |
| 695 bool isNumber() => (this.flag & (FLAG_INTEGER | FLAG_DOUBLE)) != 0; | 700 bool isNumber() => (this.flag & (FLAG_INTEGER | FLAG_DOUBLE)) != 0; |
| 696 bool isStringOrArray() => | 701 bool isStringOrArray() => |
| 697 (this.flag & (FLAG_STRING | FLAG_READABLE_ARRAY)) != 0; | 702 (this.flag & (FLAG_STRING | FLAG_READABLE_ARRAY)) != 0; |
| 703 bool isNonPrimitive() => this.flag === FLAG_NON_PRIMITIVE; | |
| 698 /** A type is useful it is not unknown and not conflicting. */ | 704 /** A type is useful it is not unknown and not conflicting. */ |
| 699 bool isUseful() => this !== UNKNOWN && this !== CONFLICTING; | 705 bool isUseful() => this !== UNKNOWN && this !== CONFLICTING; |
| 700 | 706 |
| 701 static HType getTypeFromFlag(int flag) { | 707 static HType getTypeFromFlag(int flag) { |
| 702 if (flag === CONFLICTING.flag) return CONFLICTING; | 708 if (flag === CONFLICTING.flag) return CONFLICTING; |
| 703 if (flag === UNKNOWN.flag) return UNKNOWN; | 709 if (flag === UNKNOWN.flag) return UNKNOWN; |
| 704 if (flag === BOOLEAN.flag) return BOOLEAN; | 710 if (flag === BOOLEAN.flag) return BOOLEAN; |
| 705 if (flag === INTEGER.flag) return INTEGER; | 711 if (flag === INTEGER.flag) return INTEGER; |
| 706 if (flag === DOUBLE.flag) return DOUBLE; | 712 if (flag === DOUBLE.flag) return DOUBLE; |
| 707 if (flag === STRING.flag) return STRING; | 713 if (flag === STRING.flag) return STRING; |
| 708 if (flag === READABLE_ARRAY.flag) return READABLE_ARRAY; | 714 if (flag === READABLE_ARRAY.flag) return READABLE_ARRAY; |
| 709 if (flag === MUTABLE_ARRAY.flag) return MUTABLE_ARRAY; | 715 if (flag === MUTABLE_ARRAY.flag) return MUTABLE_ARRAY; |
| 710 if (flag === NUMBER.flag) return NUMBER; | 716 if (flag === NUMBER.flag) return NUMBER; |
| 711 if (flag === STRING_OR_ARRAY.flag) return STRING_OR_ARRAY; | 717 if (flag === STRING_OR_ARRAY.flag) return STRING_OR_ARRAY; |
| 712 assert(false); | 718 unreachable(); |
| 713 } | 719 } |
| 714 | 720 |
| 715 String toString() { | 721 String toString() { |
| 716 if (isConflicting()) return 'conflicting'; | 722 if (isConflicting()) return 'conflicting'; |
| 717 if (isUnknown()) return 'unknown'; | 723 if (isUnknown()) return 'unknown'; |
| 718 if (isBoolean()) return 'boolean'; | 724 if (isBoolean()) return 'boolean'; |
| 719 if (isInteger()) return 'integer'; | 725 if (isInteger()) return 'integer'; |
| 720 if (isDouble()) return 'double'; | 726 if (isDouble()) return 'double'; |
| 721 if (isString()) return 'string'; | 727 if (isString()) return 'string'; |
| 722 if (isMutableArray()) return 'mutable array'; | 728 if (isMutableArray()) return 'mutable array'; |
| 723 if (isArray()) return 'array'; | 729 if (isArray()) return 'array'; |
| 724 if (isNumber()) return 'number'; | 730 if (isNumber()) return 'number'; |
| 725 if (isStringOrArray()) return 'string or array'; | 731 if (isStringOrArray()) return 'string or array'; |
| 726 unreachable(); | 732 unreachable(); |
| 727 } | 733 } |
| 728 | 734 |
| 729 HType combine(HType other) { | 735 HType combine(HType other) { |
| 730 if (isUnknown()) return other; | 736 if (isUnknown()) return other; |
| 731 if (other.isUnknown()) return this; | 737 if (other.isUnknown()) return this; |
| 732 return getTypeFromFlag(this.flag & other.flag); | 738 return getTypeFromFlag(this.flag & other.flag); |
| 733 } | 739 } |
| 734 } | 740 } |
| 735 | 741 |
| 742 class HNonPrimitiveType extends HType { | |
|
kasperl
2012/04/19 06:46:19
Would it make sense to have a HPrimitiveType too s
ngeoffray
2012/04/19 08:09:33
Yes, added a TODO.
| |
| 743 final Type type; | |
| 744 | |
| 745 const HNonPrimitiveType(Type this.type) : super(FLAG_NON_PRIMITIVE); | |
| 746 | |
| 747 HType combine(HType other) { | |
| 748 if (this === other) return this; | |
|
floitsch
2012/04/18 19:18:48
Why do you not look at the type?
We could even hav
ngeoffray
2012/04/19 08:09:33
Well spotted. We don;t need to think about canonic
| |
| 749 if (other.isUnknown()) return this; | |
| 750 return CONFLICTING; | |
| 751 } | |
| 752 | |
| 753 String toString() => type.toString(); | |
| 754 Element lookupMember(SourceString name) => type.element.lookupMember(name); | |
| 755 } | |
| 756 | |
| 736 class HInstruction implements Hashable { | 757 class HInstruction implements Hashable { |
| 737 final int id; | 758 final int id; |
| 738 static int idCounter; | 759 static int idCounter; |
| 739 | 760 |
| 740 final List<HInstruction> inputs; | 761 final List<HInstruction> inputs; |
| 741 final List<HInstruction> usedBy; | 762 final List<HInstruction> usedBy; |
| 742 | 763 |
| 743 HBasicBlock block; | 764 HBasicBlock block; |
| 744 HInstruction previous = null; | 765 HInstruction previous = null; |
| 745 HInstruction next = null; | 766 HInstruction next = null; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 784 // All isFunctions work on the propagated types. | 805 // All isFunctions work on the propagated types. |
| 785 bool isArray() => propagatedType.isArray(); | 806 bool isArray() => propagatedType.isArray(); |
| 786 bool isMutableArray() => propagatedType.isMutableArray(); | 807 bool isMutableArray() => propagatedType.isMutableArray(); |
| 787 bool isBoolean() => propagatedType.isBoolean(); | 808 bool isBoolean() => propagatedType.isBoolean(); |
| 788 bool isInteger() => propagatedType.isInteger(); | 809 bool isInteger() => propagatedType.isInteger(); |
| 789 bool isDouble() => propagatedType.isDouble(); | 810 bool isDouble() => propagatedType.isDouble(); |
| 790 bool isNumber() => propagatedType.isNumber(); | 811 bool isNumber() => propagatedType.isNumber(); |
| 791 bool isString() => propagatedType.isString(); | 812 bool isString() => propagatedType.isString(); |
| 792 bool isTypeUnknown() => propagatedType.isUnknown(); | 813 bool isTypeUnknown() => propagatedType.isUnknown(); |
| 793 bool isStringOrArray() => propagatedType.isStringOrArray(); | 814 bool isStringOrArray() => propagatedType.isStringOrArray(); |
| 815 bool isNonPrimitive() => propagatedType.isNonPrimitive(); | |
| 794 | 816 |
| 795 /** | 817 /** |
| 796 * This is the type the instruction is guaranteed to have. It does not | 818 * This is the type the instruction is guaranteed to have. It does not |
| 797 * take any propagation into account. | 819 * take any propagation into account. |
| 798 */ | 820 */ |
| 799 HType get guaranteedType() => HType.UNKNOWN; | 821 HType get guaranteedType() => HType.UNKNOWN; |
| 800 bool hasGuaranteedType() => !guaranteedType.isUnknown(); | 822 bool hasGuaranteedType() => !guaranteedType.isUnknown(); |
| 801 | 823 |
| 802 /** | 824 /** |
| 803 * The [propagatedType] is the type the instruction is assumed to have. | 825 * The [propagatedType] is the type the instruction is assumed to have. |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 926 } | 948 } |
| 927 } | 949 } |
| 928 this.block = null; | 950 this.block = null; |
| 929 assert(isValid()); | 951 assert(isValid()); |
| 930 } | 952 } |
| 931 | 953 |
| 932 bool isConstant() => false; | 954 bool isConstant() => false; |
| 933 bool isConstantNull() => false; | 955 bool isConstantNull() => false; |
| 934 bool isConstantNumber() => false; | 956 bool isConstantNumber() => false; |
| 935 bool isConstantString() => false; | 957 bool isConstantString() => false; |
| 958 bool isConstantList() => false; | |
| 959 bool isConstantMap() => false; | |
| 936 | 960 |
| 937 bool isValid() { | 961 bool isValid() { |
| 938 HValidator validator = new HValidator(); | 962 HValidator validator = new HValidator(); |
| 939 validator.currentBlock = block; | 963 validator.currentBlock = block; |
| 940 validator.visitInstruction(this); | 964 validator.visitInstruction(this); |
| 941 return validator.isValid; | 965 return validator.isValid; |
| 942 } | 966 } |
| 943 | 967 |
| 944 /** | 968 /** |
| 945 * The code for computing a bailout environment, and the code | 969 * The code for computing a bailout environment, and the code |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1051 */ | 1075 */ |
| 1052 final Selector selector; | 1076 final Selector selector; |
| 1053 HInvoke(Selector this.selector, List<HInstruction> inputs) : super(inputs); | 1077 HInvoke(Selector this.selector, List<HInstruction> inputs) : super(inputs); |
| 1054 static final int ARGUMENTS_OFFSET = 1; | 1078 static final int ARGUMENTS_OFFSET = 1; |
| 1055 | 1079 |
| 1056 // TODO(floitsch): make class abstract instead of adding an abstract method. | 1080 // TODO(floitsch): make class abstract instead of adding an abstract method. |
| 1057 abstract accept(HVisitor visitor); | 1081 abstract accept(HVisitor visitor); |
| 1058 } | 1082 } |
| 1059 | 1083 |
| 1060 class HInvokeDynamic extends HInvoke { | 1084 class HInvokeDynamic extends HInvoke { |
| 1085 Element element; | |
| 1061 SourceString name; | 1086 SourceString name; |
| 1062 HInvokeDynamic(Selector selector, this.name, List<HInstruction> inputs) | 1087 HInvokeDynamic(Selector selector, this.name, List<HInstruction> inputs) |
| 1063 : super(selector, inputs); | 1088 : super(selector, inputs); |
| 1064 toString() => 'invoke dynamic: $name'; | 1089 toString() => 'invoke dynamic: $name'; |
| 1065 HInstruction get receiver() => inputs[0]; | 1090 HInstruction get receiver() => inputs[0]; |
| 1066 | 1091 |
| 1067 // TODO(floitsch): make class abstract instead of adding an abstract method. | 1092 // TODO(floitsch): make class abstract instead of adding an abstract method. |
| 1068 abstract accept(HVisitor visitor); | 1093 abstract accept(HVisitor visitor); |
| 1069 } | 1094 } |
| 1070 | 1095 |
| 1071 class HInvokeClosure extends HInvokeDynamic { | 1096 class HInvokeClosure extends HInvokeDynamic { |
| 1072 Element element; | |
| 1073 HInvokeClosure(Selector selector, List<HInstruction> inputs) | 1097 HInvokeClosure(Selector selector, List<HInstruction> inputs) |
| 1074 : super(selector, const SourceString('call'), inputs); | 1098 : super(selector, const SourceString('call'), inputs); |
| 1075 accept(HVisitor visitor) => visitor.visitInvokeClosure(this); | 1099 accept(HVisitor visitor) => visitor.visitInvokeClosure(this); |
| 1076 } | 1100 } |
| 1077 | 1101 |
| 1078 class HInvokeDynamicMethod extends HInvokeDynamic { | 1102 class HInvokeDynamicMethod extends HInvokeDynamic { |
| 1079 HInvokeDynamicMethod(Selector selector, | 1103 HInvokeDynamicMethod(Selector selector, |
| 1080 SourceString methodName, | 1104 SourceString methodName, |
| 1081 List<HInstruction> inputs) | 1105 List<HInstruction> inputs) |
| 1082 : super(selector, methodName, inputs); | 1106 : super(selector, methodName, inputs); |
| 1083 toString() => 'invoke dynamic method: $name'; | 1107 toString() => 'invoke dynamic method: $name'; |
| 1084 accept(HVisitor visitor) => visitor.visitInvokeDynamicMethod(this); | 1108 accept(HVisitor visitor) => visitor.visitInvokeDynamicMethod(this); |
| 1085 } | 1109 } |
| 1086 | 1110 |
| 1087 class HInvokeDynamicField extends HInvokeDynamic { | 1111 class HInvokeDynamicField extends HInvokeDynamic { |
| 1088 Element element; | |
| 1089 HInvokeDynamicField(Selector selector, | 1112 HInvokeDynamicField(Selector selector, |
| 1090 Element this.element, | 1113 Element element, |
| 1091 SourceString name, | 1114 SourceString name, |
| 1092 List<HInstruction>inputs) | 1115 List<HInstruction>inputs) |
| 1093 : super(selector, name, inputs); | 1116 : super(selector, name, inputs) { |
| 1117 this.element = element; | |
|
floitsch
2012/04/18 19:18:48
I would prefer passing the element in the super ca
ngeoffray
2012/04/19 08:09:33
Done.
| |
| 1118 } | |
| 1094 toString() => 'invoke dynamic field: $name'; | 1119 toString() => 'invoke dynamic field: $name'; |
| 1095 | 1120 |
| 1096 // TODO(floitsch): make class abstract instead of adding an abstract method. | 1121 // TODO(floitsch): make class abstract instead of adding an abstract method. |
| 1097 abstract accept(HVisitor visitor); | 1122 abstract accept(HVisitor visitor); |
| 1098 } | 1123 } |
| 1099 | 1124 |
| 1100 class HInvokeDynamicGetter extends HInvokeDynamicField { | 1125 class HInvokeDynamicGetter extends HInvokeDynamicField { |
| 1101 HInvokeDynamicGetter(selector, element, name, receiver) | 1126 HInvokeDynamicGetter(selector, element, name, receiver) |
| 1102 : super(selector, element, name, [receiver]); | 1127 : super(selector, element, name, [receiver]); |
| 1103 toString() => 'invoke dynamic getter: $name'; | 1128 toString() => 'invoke dynamic getter: $name'; |
| 1104 accept(HVisitor visitor) => visitor.visitInvokeDynamicGetter(this); | 1129 accept(HVisitor visitor) => visitor.visitInvokeDynamicGetter(this); |
| 1105 } | 1130 } |
| 1106 | 1131 |
| 1107 class HInvokeDynamicSetter extends HInvokeDynamicField { | 1132 class HInvokeDynamicSetter extends HInvokeDynamicField { |
| 1108 HInvokeDynamicSetter(selector, element, name, receiver, value) | 1133 HInvokeDynamicSetter(selector, element, name, receiver, value) |
| 1109 : super(selector, element, name, [receiver, value]); | 1134 : super(selector, element, name, [receiver, value]); |
| 1110 toString() => 'invoke dynamic setter: $name'; | 1135 toString() => 'invoke dynamic setter: $name'; |
| 1111 accept(HVisitor visitor) => visitor.visitInvokeDynamicSetter(this); | 1136 accept(HVisitor visitor) => visitor.visitInvokeDynamicSetter(this); |
| 1112 } | 1137 } |
| 1113 | 1138 |
| 1114 class HInvokeStatic extends HInvoke { | 1139 class HInvokeStatic extends HInvoke { |
| 1140 final HType concreteType; | |
| 1115 /** The first input must be the target. */ | 1141 /** The first input must be the target. */ |
| 1116 HInvokeStatic(selector, inputs) : super(selector, inputs); | 1142 HInvokeStatic(selector, inputs, [this.concreteType = HType.UNKNOWN]) |
| 1143 : super(selector, inputs); | |
| 1117 toString() => 'invoke static: ${element.name}'; | 1144 toString() => 'invoke static: ${element.name}'; |
| 1118 accept(HVisitor visitor) => visitor.visitInvokeStatic(this); | 1145 accept(HVisitor visitor) => visitor.visitInvokeStatic(this); |
| 1119 Element get element() => target.element; | 1146 Element get element() => target.element; |
| 1120 HStatic get target() => inputs[0]; | 1147 HStatic get target() => inputs[0]; |
| 1121 | 1148 |
| 1122 bool isArrayConstructor() { | 1149 HType get guaranteedType() => concreteType; |
| 1123 // TODO(ngeoffray): This is not the right way to do the check, | |
| 1124 // nor the right place. We need to move it to a phase. | |
| 1125 return (element.isFactoryConstructor() | |
| 1126 && element.enclosingElement.name.slowToString() == 'List'); | |
| 1127 } | |
| 1128 | |
| 1129 HType get guaranteedType() { | |
| 1130 if (isArrayConstructor()) { | |
| 1131 return HType.MUTABLE_ARRAY; | |
| 1132 } | |
| 1133 return HType.UNKNOWN; | |
| 1134 } | |
| 1135 | 1150 |
| 1136 HType computeDesiredTypeForInput(HInstruction input) { | 1151 HType computeDesiredTypeForInput(HInstruction input) { |
| 1137 // TODO(floitsch): we want the target to be a function. | 1152 // TODO(floitsch): we want the target to be a function. |
| 1138 if (input == target) return HType.UNKNOWN; | 1153 if (input == target) return HType.UNKNOWN; |
| 1139 return computeDesiredTypeForNonTargetInput(input); | 1154 return computeDesiredTypeForNonTargetInput(input); |
| 1140 } | 1155 } |
| 1141 | 1156 |
| 1142 HType computeDesiredTypeForNonTargetInput(HInstruction input) { | 1157 HType computeDesiredTypeForNonTargetInput(HInstruction input) { |
| 1143 return HType.UNKNOWN; | 1158 return HType.UNKNOWN; |
| 1144 } | 1159 } |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 1157 final bool getter; | 1172 final bool getter; |
| 1158 | 1173 |
| 1159 HInvokeInterceptor(Selector selector, | 1174 HInvokeInterceptor(Selector selector, |
| 1160 SourceString this.name, | 1175 SourceString this.name, |
| 1161 bool this.getter, | 1176 bool this.getter, |
| 1162 List<HInstruction> inputs) | 1177 List<HInstruction> inputs) |
| 1163 : super(selector, inputs); | 1178 : super(selector, inputs); |
| 1164 toString() => 'invoke interceptor: ${element.name}'; | 1179 toString() => 'invoke interceptor: ${element.name}'; |
| 1165 accept(HVisitor visitor) => visitor.visitInvokeInterceptor(this); | 1180 accept(HVisitor visitor) => visitor.visitInvokeInterceptor(this); |
| 1166 | 1181 |
| 1182 bool isLengthGetter() { | |
| 1183 return getter | |
|
floitsch
2012/04/18 19:18:48
one line.
kasperl
2012/04/19 06:46:19
Fits on one line?
ngeoffray
2012/04/19 08:09:33
Done.
| |
| 1184 && name == const SourceString('length'); | |
| 1185 } | |
| 1186 | |
| 1167 bool isLengthGetterOnStringOrArray() { | 1187 bool isLengthGetterOnStringOrArray() { |
| 1168 return getter | 1188 return isLengthGetter() |
| 1169 && name == const SourceString('length') | |
| 1170 && inputs[1].isStringOrArray(); | 1189 && inputs[1].isStringOrArray(); |
| 1171 } | 1190 } |
| 1172 | 1191 |
| 1173 String get builtinJsName() { | 1192 String get builtinJsName() { |
| 1174 if (isLengthGetterOnStringOrArray()) { | 1193 if (isLengthGetterOnStringOrArray()) { |
| 1175 return 'length'; | 1194 return 'length'; |
| 1176 } else if (name == const SourceString('add') | 1195 } else if (name == const SourceString('add') |
| 1177 && inputs[1].isMutableArray()) { | 1196 && inputs[1].isMutableArray()) { |
| 1178 return 'push'; | 1197 return 'push'; |
| 1179 } else if (name == const SourceString('removeLast') | 1198 } else if (name == const SourceString('removeLast') |
| (...skipping 535 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1715 toString() => 'literal: $constant'; | 1734 toString() => 'literal: $constant'; |
| 1716 accept(HVisitor visitor) => visitor.visitConstant(this); | 1735 accept(HVisitor visitor) => visitor.visitConstant(this); |
| 1717 | 1736 |
| 1718 HType get guaranteedType() => constantType; | 1737 HType get guaranteedType() => constantType; |
| 1719 | 1738 |
| 1720 bool isConstant() => true; | 1739 bool isConstant() => true; |
| 1721 bool isConstantBoolean() => constant.isBool(); | 1740 bool isConstantBoolean() => constant.isBool(); |
| 1722 bool isConstantNull() => constant.isNull(); | 1741 bool isConstantNull() => constant.isNull(); |
| 1723 bool isConstantNumber() => constant.isNum(); | 1742 bool isConstantNumber() => constant.isNum(); |
| 1724 bool isConstantString() => constant.isString(); | 1743 bool isConstantString() => constant.isString(); |
| 1744 bool isConstantList() => constant.isList(); | |
| 1745 bool isConstantMap() => constant.isMap(); | |
| 1725 | 1746 |
| 1726 // Maybe avoid this if the literal is big? | 1747 // Maybe avoid this if the literal is big? |
| 1727 bool isCodeMotionInvariant() => true; | 1748 bool isCodeMotionInvariant() => true; |
| 1728 } | 1749 } |
| 1729 | 1750 |
| 1730 class HNot extends HInstruction { | 1751 class HNot extends HInstruction { |
| 1731 HNot(HInstruction value) : super(<HInstruction>[value]); | 1752 HNot(HInstruction value) : super(<HInstruction>[value]); |
| 1732 void prepareGvn() { | 1753 void prepareGvn() { |
| 1733 assert(!hasSideEffects()); | 1754 assert(!hasSideEffects()); |
| 1734 setUseGvn(); | 1755 setUseGvn(); |
| (...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2256 final bool isAnd; | 2277 final bool isAnd; |
| 2257 final SubExpression left; | 2278 final SubExpression left; |
| 2258 final SubExpression right; | 2279 final SubExpression right; |
| 2259 final HBasicBlock joinBlock; | 2280 final HBasicBlock joinBlock; |
| 2260 HAndOrBlockInformation(this.isAnd, | 2281 HAndOrBlockInformation(this.isAnd, |
| 2261 this.left, | 2282 this.left, |
| 2262 this.right, | 2283 this.right, |
| 2263 this.joinBlock); | 2284 this.joinBlock); |
| 2264 bool accept(HBlockInformationVisitor visitor) => visitor.visitAndOrInfo(this); | 2285 bool accept(HBlockInformationVisitor visitor) => visitor.visitAndOrInfo(this); |
| 2265 } | 2286 } |
| OLD | NEW |