| 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 660 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 671 const HType(int this.flag); | 671 const HType(int this.flag); |
| 672 | 672 |
| 673 static final int FLAG_CONFLICTING = 0; | 673 static final int FLAG_CONFLICTING = 0; |
| 674 static final int FLAG_UNKNOWN = 1; | 674 static final int FLAG_UNKNOWN = 1; |
| 675 static final int FLAG_BOOLEAN = FLAG_UNKNOWN << 1; | 675 static final int FLAG_BOOLEAN = FLAG_UNKNOWN << 1; |
| 676 static final int FLAG_INTEGER = FLAG_BOOLEAN << 1; | 676 static final int FLAG_INTEGER = FLAG_BOOLEAN << 1; |
| 677 static final int FLAG_STRING = FLAG_INTEGER << 1; | 677 static final int FLAG_STRING = FLAG_INTEGER << 1; |
| 678 static final int FLAG_READABLE_ARRAY = FLAG_STRING << 1; | 678 static final int FLAG_READABLE_ARRAY = FLAG_STRING << 1; |
| 679 // FLAG_WRITABLE_ARRAY implies FLAG_READABLE_ARRAY. | 679 // FLAG_WRITABLE_ARRAY implies FLAG_READABLE_ARRAY. |
| 680 static final int FLAG_WRITEABLE_ARRAY = FLAG_READABLE_ARRAY << 1; | 680 static final int FLAG_WRITEABLE_ARRAY = FLAG_READABLE_ARRAY << 1; |
| 681 static final int FLAG_DOUBLE = FLAG_WRITEABLE_ARRAY << 1; | 681 static final int FLAG_EXTENDABLE_ARRAY = FLAG_WRITEABLE_ARRAY << 1; |
| 682 static final int FLAG_DOUBLE = FLAG_EXTENDABLE_ARRAY << 1; |
| 682 static final int FLAG_NON_PRIMITIVE = FLAG_DOUBLE << 1; | 683 static final int FLAG_NON_PRIMITIVE = FLAG_DOUBLE << 1; |
| 683 | 684 |
| 684 static final HType CONFLICTING = const HType(FLAG_CONFLICTING); | 685 static final HType CONFLICTING = const HType(FLAG_CONFLICTING); |
| 685 static final HType UNKNOWN = const HType(FLAG_UNKNOWN); | 686 static final HType UNKNOWN = const HType(FLAG_UNKNOWN); |
| 686 static final HType BOOLEAN = const HType(FLAG_BOOLEAN); | 687 static final HType BOOLEAN = const HType(FLAG_BOOLEAN); |
| 687 static final HType STRING = const HType(FLAG_STRING); | 688 static final HType STRING = const HType(FLAG_STRING); |
| 688 static final HType READABLE_ARRAY = const HType(FLAG_READABLE_ARRAY); | 689 static final HType READABLE_ARRAY = const HType(FLAG_READABLE_ARRAY); |
| 689 static final HType MUTABLE_ARRAY = | 690 static final HType MUTABLE_ARRAY = const HType( |
| 690 const HType(FLAG_READABLE_ARRAY | FLAG_WRITEABLE_ARRAY); | 691 FLAG_READABLE_ARRAY | FLAG_WRITEABLE_ARRAY); |
| 692 static final HType EXTENDABLE_ARRAY = const HType( |
| 693 FLAG_READABLE_ARRAY | FLAG_WRITEABLE_ARRAY | FLAG_EXTENDABLE_ARRAY); |
| 691 static final HType INTEGER = const HType(FLAG_INTEGER); | 694 static final HType INTEGER = const HType(FLAG_INTEGER); |
| 692 static final HType DOUBLE = const HType(FLAG_DOUBLE); | 695 static final HType DOUBLE = const HType(FLAG_DOUBLE); |
| 693 static final HType STRING_OR_ARRAY = | 696 static final HType STRING_OR_ARRAY = const HType( |
| 694 const HType(FLAG_STRING | FLAG_READABLE_ARRAY | FLAG_WRITEABLE_ARRAY); | 697 FLAG_STRING | FLAG_READABLE_ARRAY | FLAG_WRITEABLE_ARRAY |
| 698 | FLAG_EXTENDABLE_ARRAY); |
| 695 static final HType NUMBER = const HType(FLAG_DOUBLE | FLAG_INTEGER); | 699 static final HType NUMBER = const HType(FLAG_DOUBLE | FLAG_INTEGER); |
| 696 | 700 |
| 697 bool isConflicting() => this === CONFLICTING; | 701 bool isConflicting() => this === CONFLICTING; |
| 698 bool isUnknown() => this === UNKNOWN; | 702 bool isUnknown() => this === UNKNOWN; |
| 699 bool isBoolean() => this === BOOLEAN; | 703 bool isBoolean() => this === BOOLEAN; |
| 700 bool isInteger() => this === INTEGER; | 704 bool isInteger() => this === INTEGER; |
| 701 bool isDouble() => this === DOUBLE; | 705 bool isDouble() => this === DOUBLE; |
| 702 bool isString() => this === STRING; | 706 bool isString() => this === STRING; |
| 703 bool isArray() => (this.flag & FLAG_READABLE_ARRAY) != 0; | 707 bool isArray() => (this.flag & FLAG_READABLE_ARRAY) != 0; |
| 704 bool isMutableArray() => this === MUTABLE_ARRAY; | 708 bool isMutableArray() => this === MUTABLE_ARRAY || this === EXTENDABLE_ARRAY; |
| 709 bool isExtendableArray() => this === EXTENDABLE_ARRAY; |
| 705 bool isNumber() => (this.flag & (FLAG_INTEGER | FLAG_DOUBLE)) != 0; | 710 bool isNumber() => (this.flag & (FLAG_INTEGER | FLAG_DOUBLE)) != 0; |
| 706 bool isStringOrArray() => | 711 bool isStringOrArray() => |
| 707 (this.flag & (FLAG_STRING | FLAG_READABLE_ARRAY)) != 0; | 712 (this.flag & (FLAG_STRING | FLAG_READABLE_ARRAY)) != 0; |
| 708 bool isNonPrimitive() => this.flag === FLAG_NON_PRIMITIVE; | 713 bool isNonPrimitive() => this.flag === FLAG_NON_PRIMITIVE; |
| 709 /** A type is useful it is not unknown and not conflicting. */ | 714 /** A type is useful it is not unknown and not conflicting. */ |
| 710 bool isUseful() => this !== UNKNOWN && this !== CONFLICTING; | 715 bool isUseful() => this !== UNKNOWN && this !== CONFLICTING; |
| 711 | 716 |
| 712 static HType getTypeFromFlag(int flag) { | 717 static HType getTypeFromFlag(int flag) { |
| 713 if (flag === CONFLICTING.flag) return CONFLICTING; | 718 if (flag === CONFLICTING.flag) return CONFLICTING; |
| 714 if (flag === UNKNOWN.flag) return UNKNOWN; | 719 if (flag === UNKNOWN.flag) return UNKNOWN; |
| 715 if (flag === BOOLEAN.flag) return BOOLEAN; | 720 if (flag === BOOLEAN.flag) return BOOLEAN; |
| 716 if (flag === INTEGER.flag) return INTEGER; | 721 if (flag === INTEGER.flag) return INTEGER; |
| 717 if (flag === DOUBLE.flag) return DOUBLE; | 722 if (flag === DOUBLE.flag) return DOUBLE; |
| 718 if (flag === STRING.flag) return STRING; | 723 if (flag === STRING.flag) return STRING; |
| 719 if (flag === READABLE_ARRAY.flag) return READABLE_ARRAY; | 724 if (flag === READABLE_ARRAY.flag) return READABLE_ARRAY; |
| 720 if (flag === MUTABLE_ARRAY.flag) return MUTABLE_ARRAY; | 725 if (flag === MUTABLE_ARRAY.flag) return MUTABLE_ARRAY; |
| 726 if (flag === EXTENDABLE_ARRAY.flag) return EXTENDABLE_ARRAY; |
| 721 if (flag === NUMBER.flag) return NUMBER; | 727 if (flag === NUMBER.flag) return NUMBER; |
| 722 if (flag === STRING_OR_ARRAY.flag) return STRING_OR_ARRAY; | 728 if (flag === STRING_OR_ARRAY.flag) return STRING_OR_ARRAY; |
| 723 unreachable(); | 729 unreachable(); |
| 724 } | 730 } |
| 725 | 731 |
| 726 String toString() { | 732 String toString() { |
| 727 if (isConflicting()) return 'conflicting'; | 733 if (isConflicting()) return 'conflicting'; |
| 728 if (isUnknown()) return 'unknown'; | 734 if (isUnknown()) return 'unknown'; |
| 729 if (isBoolean()) return 'boolean'; | 735 if (isBoolean()) return 'boolean'; |
| 730 if (isInteger()) return 'integer'; | 736 if (isInteger()) return 'integer'; |
| 731 if (isDouble()) return 'double'; | 737 if (isDouble()) return 'double'; |
| 732 if (isString()) return 'string'; | 738 if (isString()) return 'string'; |
| 733 if (isMutableArray()) return 'mutable array'; | 739 if (isMutableArray()) return 'mutable array'; |
| 740 if (isExtendableArray()) return 'extendable array'; |
| 734 if (isArray()) return 'array'; | 741 if (isArray()) return 'array'; |
| 735 if (isNumber()) return 'number'; | 742 if (isNumber()) return 'number'; |
| 736 if (isStringOrArray()) return 'string or array'; | 743 if (isStringOrArray()) return 'string or array'; |
| 737 unreachable(); | 744 unreachable(); |
| 738 } | 745 } |
| 739 | 746 |
| 740 HType combine(HType other) { | 747 HType combine(HType other) { |
| 741 if (isUnknown()) return other; | 748 if (isUnknown()) return other; |
| 742 if (other.isUnknown()) return this; | 749 if (other.isUnknown()) return this; |
| 743 return getTypeFromFlag(this.flag & other.flag); | 750 return getTypeFromFlag(this.flag & other.flag); |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 812 void clearAllSideEffects() { flags &= ~((1 << FLAG_CHANGES_COUNT) - 1); } | 819 void clearAllSideEffects() { flags &= ~((1 << FLAG_CHANGES_COUNT) - 1); } |
| 813 | 820 |
| 814 bool useGvn() => getFlag(FLAG_USE_GVN); | 821 bool useGvn() => getFlag(FLAG_USE_GVN); |
| 815 void setUseGvn() { setFlag(FLAG_USE_GVN); } | 822 void setUseGvn() { setFlag(FLAG_USE_GVN); } |
| 816 // Does this node potentially affect control flow. | 823 // Does this node potentially affect control flow. |
| 817 bool isControlFlow() => false; | 824 bool isControlFlow() => false; |
| 818 | 825 |
| 819 // All isFunctions work on the propagated types. | 826 // All isFunctions work on the propagated types. |
| 820 bool isArray() => propagatedType.isArray(); | 827 bool isArray() => propagatedType.isArray(); |
| 821 bool isMutableArray() => propagatedType.isMutableArray(); | 828 bool isMutableArray() => propagatedType.isMutableArray(); |
| 829 bool isExtendableArray() => propagatedType.isExtendableArray(); |
| 822 bool isBoolean() => propagatedType.isBoolean(); | 830 bool isBoolean() => propagatedType.isBoolean(); |
| 823 bool isInteger() => propagatedType.isInteger(); | 831 bool isInteger() => propagatedType.isInteger(); |
| 824 bool isDouble() => propagatedType.isDouble(); | 832 bool isDouble() => propagatedType.isDouble(); |
| 825 bool isNumber() => propagatedType.isNumber(); | 833 bool isNumber() => propagatedType.isNumber(); |
| 826 bool isString() => propagatedType.isString(); | 834 bool isString() => propagatedType.isString(); |
| 827 bool isTypeUnknown() => propagatedType.isUnknown(); | 835 bool isTypeUnknown() => propagatedType.isUnknown(); |
| 828 bool isStringOrArray() => propagatedType.isStringOrArray(); | 836 bool isStringOrArray() => propagatedType.isStringOrArray(); |
| 829 bool isNonPrimitive() => propagatedType.isNonPrimitive(); | 837 bool isNonPrimitive() => propagatedType.isNonPrimitive(); |
| 830 | 838 |
| 831 /** | 839 /** |
| (...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1204 | 1212 |
| 1205 bool isLengthGetterOnStringOrArray() { | 1213 bool isLengthGetterOnStringOrArray() { |
| 1206 return isLengthGetter() | 1214 return isLengthGetter() |
| 1207 && inputs[1].isStringOrArray(); | 1215 && inputs[1].isStringOrArray(); |
| 1208 } | 1216 } |
| 1209 | 1217 |
| 1210 String get builtinJsName() { | 1218 String get builtinJsName() { |
| 1211 if (isLengthGetterOnStringOrArray()) { | 1219 if (isLengthGetterOnStringOrArray()) { |
| 1212 return 'length'; | 1220 return 'length'; |
| 1213 } else if (name == const SourceString('add') | 1221 } else if (name == const SourceString('add') |
| 1214 && inputs[1].isMutableArray()) { | 1222 && inputs[1].isExtendableArray()) { |
| 1215 return 'push'; | 1223 return 'push'; |
| 1216 } else if (name == const SourceString('removeLast') | 1224 } else if (name == const SourceString('removeLast') |
| 1217 && inputs[1].isMutableArray()) { | 1225 && inputs[1].isExtendableArray()) { |
| 1218 return 'pop'; | 1226 return 'pop'; |
| 1219 } | 1227 } |
| 1220 return null; | 1228 return null; |
| 1221 } | 1229 } |
| 1222 | 1230 |
| 1223 HType get guaranteedType() => HType.UNKNOWN; | 1231 HType get guaranteedType() => HType.UNKNOWN; |
| 1224 | 1232 |
| 1225 HType get likelyType() { | 1233 HType get likelyType() { |
| 1226 // In general a length getter or method returns an int. | 1234 // In general a length getter or method returns an int. |
| 1227 if (name == const SourceString('length')) return HType.INTEGER; | 1235 if (name == const SourceString('length')) return HType.INTEGER; |
| (...skipping 1076 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2304 final bool isAnd; | 2312 final bool isAnd; |
| 2305 final SubExpression left; | 2313 final SubExpression left; |
| 2306 final SubExpression right; | 2314 final SubExpression right; |
| 2307 final HBasicBlock joinBlock; | 2315 final HBasicBlock joinBlock; |
| 2308 HAndOrBlockInformation(this.isAnd, | 2316 HAndOrBlockInformation(this.isAnd, |
| 2309 this.left, | 2317 this.left, |
| 2310 this.right, | 2318 this.right, |
| 2311 this.joinBlock); | 2319 this.joinBlock); |
| 2312 bool accept(HBlockInformationVisitor visitor) => visitor.visitAndOrInfo(this); | 2320 bool accept(HBlockInformationVisitor visitor) => visitor.visitAndOrInfo(this); |
| 2313 } | 2321 } |
| OLD | NEW |