| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 part of ssa; | 5 part of ssa; |
| 6 | 6 |
| 7 abstract class HVisitor<R> { | 7 abstract class HVisitor<R> { |
| 8 R visitAdd(HAdd node); | 8 R visitAdd(HAdd node); |
| 9 R visitAwait(HAwait node); | 9 R visitAwait(HAwait node); |
| 10 R visitBitAnd(HBitAnd node); | 10 R visitBitAnd(HBitAnd node); |
| (...skipping 864 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 875 | 875 |
| 876 bool isExact() => instructionType.isExact || isNull(); | 876 bool isExact() => instructionType.isExact || isNull(); |
| 877 | 877 |
| 878 bool canBeNull() => instructionType.isNullable; | 878 bool canBeNull() => instructionType.isNullable; |
| 879 | 879 |
| 880 bool isNull() => instructionType.isEmpty && instructionType.isNullable; | 880 bool isNull() => instructionType.isEmpty && instructionType.isNullable; |
| 881 bool isConflicting() { | 881 bool isConflicting() { |
| 882 return instructionType.isEmpty && !instructionType.isNullable; | 882 return instructionType.isEmpty && !instructionType.isNullable; |
| 883 } | 883 } |
| 884 | 884 |
| 885 /// Returns `true` if [typeMask] contains [cls]. |
| 886 static bool containsType( |
| 887 TypeMask typeMask, |
| 888 ClassElement cls, |
| 889 ClassWorld classWorld) { |
| 890 return classWorld.isInstantiated(cls) && typeMask.contains(cls, classWorld); |
| 891 } |
| 892 |
| 893 /// Returns `true` if [typeMask] contains only [cls]. |
| 894 static bool containsOnlyType( |
| 895 TypeMask typeMask, |
| 896 ClassElement cls, |
| 897 ClassWorld classWorld) { |
| 898 return classWorld.isInstantiated(cls) && |
| 899 typeMask.containsOnly(cls); |
| 900 } |
| 901 |
| 902 /// Returns `true` if [typeMask] is an instance of [cls]. |
| 903 static bool isInstanceOf( |
| 904 TypeMask typeMask, |
| 905 ClassElement cls, |
| 906 ClassWorld classWorld) { |
| 907 return classWorld.isInstantiated(cls) && |
| 908 typeMask.satisfies(cls, classWorld); |
| 909 } |
| 910 |
| 885 bool canBePrimitive(Compiler compiler) { | 911 bool canBePrimitive(Compiler compiler) { |
| 886 return canBePrimitiveNumber(compiler) | 912 return canBePrimitiveNumber(compiler) |
| 887 || canBePrimitiveArray(compiler) | 913 || canBePrimitiveArray(compiler) |
| 888 || canBePrimitiveBoolean(compiler) | 914 || canBePrimitiveBoolean(compiler) |
| 889 || canBePrimitiveString(compiler) | 915 || canBePrimitiveString(compiler) |
| 890 || isNull(); | 916 || isNull(); |
| 891 } | 917 } |
| 892 | 918 |
| 893 bool canBePrimitiveNumber(Compiler compiler) { | 919 bool canBePrimitiveNumber(Compiler compiler) { |
| 894 ClassWorld classWorld = compiler.world; | 920 ClassWorld classWorld = compiler.world; |
| 895 JavaScriptBackend backend = compiler.backend; | 921 JavaScriptBackend backend = compiler.backend; |
| 896 // TODO(sra): It should be possible to test only jsDoubleClass and | 922 // TODO(sra): It should be possible to test only jsDoubleClass and |
| 897 // jsUInt31Class, since all others are superclasses of these two. | 923 // jsUInt31Class, since all others are superclasses of these two. |
| 898 return instructionType.contains(backend.jsNumberClass, classWorld) | 924 return containsType(instructionType, backend.jsNumberClass, classWorld) |
| 899 || instructionType.contains(backend.jsIntClass, classWorld) | 925 || containsType(instructionType, backend.jsIntClass, classWorld) |
| 900 || instructionType.contains(backend.jsPositiveIntClass, classWorld) | 926 || containsType(instructionType, backend.jsPositiveIntClass, classWorld) |
| 901 || instructionType.contains(backend.jsUInt32Class, classWorld) | 927 || containsType(instructionType, backend.jsUInt32Class, classWorld) |
| 902 || instructionType.contains(backend.jsUInt31Class, classWorld) | 928 || containsType(instructionType, backend.jsUInt31Class, classWorld) |
| 903 || instructionType.contains(backend.jsDoubleClass, classWorld); | 929 || containsType(instructionType, backend.jsDoubleClass, classWorld); |
| 904 } | 930 } |
| 905 | 931 |
| 906 bool canBePrimitiveBoolean(Compiler compiler) { | 932 bool canBePrimitiveBoolean(Compiler compiler) { |
| 907 ClassWorld classWorld = compiler.world; | 933 ClassWorld classWorld = compiler.world; |
| 908 JavaScriptBackend backend = compiler.backend; | 934 JavaScriptBackend backend = compiler.backend; |
| 909 return instructionType.contains(backend.jsBoolClass, classWorld); | 935 return containsType(instructionType, backend.jsBoolClass, classWorld); |
| 910 } | 936 } |
| 911 | 937 |
| 912 bool canBePrimitiveArray(Compiler compiler) { | 938 bool canBePrimitiveArray(Compiler compiler) { |
| 913 ClassWorld classWorld = compiler.world; | 939 ClassWorld classWorld = compiler.world; |
| 914 JavaScriptBackend backend = compiler.backend; | 940 JavaScriptBackend backend = compiler.backend; |
| 915 return instructionType.contains(backend.jsArrayClass, classWorld) | 941 return containsType(instructionType, backend.jsArrayClass, classWorld) |
| 916 || instructionType.contains(backend.jsFixedArrayClass, classWorld) | 942 || containsType(instructionType, backend.jsFixedArrayClass, classWorld) |
| 917 || instructionType.contains(backend.jsExtendableArrayClass, classWorld) | 943 || containsType( |
| 918 || instructionType.contains( | 944 instructionType, backend.jsExtendableArrayClass, classWorld) |
| 945 || containsType(instructionType, |
| 919 backend.jsUnmodifiableArrayClass, classWorld); | 946 backend.jsUnmodifiableArrayClass, classWorld); |
| 920 } | 947 } |
| 921 | 948 |
| 922 bool isIndexablePrimitive(Compiler compiler) { | 949 bool isIndexablePrimitive(Compiler compiler) { |
| 923 ClassWorld classWorld = compiler.world; | 950 ClassWorld classWorld = compiler.world; |
| 924 JavaScriptBackend backend = compiler.backend; | 951 JavaScriptBackend backend = compiler.backend; |
| 925 return instructionType.containsOnlyString(classWorld) | 952 return instructionType.containsOnlyString(classWorld) |
| 926 || instructionType.satisfies(backend.jsIndexableClass, classWorld); | 953 || isInstanceOf(instructionType, backend.jsIndexableClass, classWorld); |
| 927 } | 954 } |
| 928 | 955 |
| 929 bool isFixedArray(Compiler compiler) { | 956 bool isFixedArray(Compiler compiler) { |
| 957 ClassWorld classWorld = compiler.world; |
| 930 JavaScriptBackend backend = compiler.backend; | 958 JavaScriptBackend backend = compiler.backend; |
| 931 // TODO(sra): Recognize the union of these types as well. | 959 // TODO(sra): Recognize the union of these types as well. |
| 932 return instructionType.containsOnly(backend.jsFixedArrayClass) | 960 return containsOnlyType( |
| 933 || instructionType.containsOnly(backend.jsUnmodifiableArrayClass); | 961 instructionType, backend.jsFixedArrayClass, classWorld) |
| 962 || containsOnlyType( |
| 963 instructionType, backend.jsUnmodifiableArrayClass, classWorld); |
| 934 } | 964 } |
| 935 | 965 |
| 936 bool isExtendableArray(Compiler compiler) { | 966 bool isExtendableArray(Compiler compiler) { |
| 967 ClassWorld classWorld = compiler.world; |
| 937 JavaScriptBackend backend = compiler.backend; | 968 JavaScriptBackend backend = compiler.backend; |
| 938 return instructionType.containsOnly(backend.jsExtendableArrayClass); | 969 return containsOnlyType( |
| 970 instructionType, backend.jsExtendableArrayClass, classWorld); |
| 939 } | 971 } |
| 940 | 972 |
| 941 bool isMutableArray(Compiler compiler) { | 973 bool isMutableArray(Compiler compiler) { |
| 942 ClassWorld classWorld = compiler.world; | 974 ClassWorld classWorld = compiler.world; |
| 943 JavaScriptBackend backend = compiler.backend; | 975 JavaScriptBackend backend = compiler.backend; |
| 944 return instructionType.satisfies(backend.jsMutableArrayClass, classWorld); | 976 return isInstanceOf( |
| 977 instructionType, backend.jsMutableArrayClass, classWorld); |
| 945 } | 978 } |
| 946 | 979 |
| 947 bool isReadableArray(Compiler compiler) { | 980 bool isReadableArray(Compiler compiler) { |
| 948 ClassWorld classWorld = compiler.world; | 981 ClassWorld classWorld = compiler.world; |
| 949 JavaScriptBackend backend = compiler.backend; | 982 JavaScriptBackend backend = compiler.backend; |
| 950 return instructionType.satisfies(backend.jsArrayClass, classWorld); | 983 return isInstanceOf(instructionType, backend.jsArrayClass, classWorld); |
| 951 } | 984 } |
| 952 | 985 |
| 953 bool isMutableIndexable(Compiler compiler) { | 986 bool isMutableIndexable(Compiler compiler) { |
| 954 ClassWorld classWorld = compiler.world; | 987 ClassWorld classWorld = compiler.world; |
| 955 JavaScriptBackend backend = compiler.backend; | 988 JavaScriptBackend backend = compiler.backend; |
| 956 return instructionType.satisfies( | 989 return isInstanceOf(instructionType, |
| 957 backend.jsMutableIndexableClass, classWorld); | 990 backend.jsMutableIndexableClass, classWorld); |
| 958 } | 991 } |
| 959 | 992 |
| 960 bool isArray(Compiler compiler) => isReadableArray(compiler); | 993 bool isArray(Compiler compiler) => isReadableArray(compiler); |
| 961 | 994 |
| 962 bool canBePrimitiveString(Compiler compiler) { | 995 bool canBePrimitiveString(Compiler compiler) { |
| 963 ClassWorld classWorld = compiler.world; | 996 ClassWorld classWorld = compiler.world; |
| 964 JavaScriptBackend backend = compiler.backend; | 997 JavaScriptBackend backend = compiler.backend; |
| 965 return instructionType.contains(backend.jsStringClass, classWorld); | 998 return containsType(instructionType, backend.jsStringClass, classWorld); |
| 966 } | 999 } |
| 967 | 1000 |
| 968 bool isInteger(Compiler compiler) { | 1001 bool isInteger(Compiler compiler) { |
| 969 ClassWorld classWorld = compiler.world; | 1002 ClassWorld classWorld = compiler.world; |
| 970 return instructionType.containsOnlyInt(classWorld) | 1003 return instructionType.containsOnlyInt(classWorld) |
| 971 && !instructionType.isNullable; | 1004 && !instructionType.isNullable; |
| 972 } | 1005 } |
| 973 | 1006 |
| 974 bool isUInt32(Compiler compiler) { | 1007 bool isUInt32(Compiler compiler) { |
| 975 ClassWorld classWorld = compiler.world; | 1008 ClassWorld classWorld = compiler.world; |
| 976 JavaScriptBackend backend = compiler.backend; | 1009 JavaScriptBackend backend = compiler.backend; |
| 977 return !instructionType.isNullable | 1010 return !instructionType.isNullable |
| 978 && instructionType.satisfies(backend.jsUInt32Class, classWorld); | 1011 && isInstanceOf(instructionType, backend.jsUInt32Class, classWorld); |
| 979 } | 1012 } |
| 980 | 1013 |
| 981 bool isUInt31(Compiler compiler) { | 1014 bool isUInt31(Compiler compiler) { |
| 982 ClassWorld classWorld = compiler.world; | 1015 ClassWorld classWorld = compiler.world; |
| 983 JavaScriptBackend backend = compiler.backend; | 1016 JavaScriptBackend backend = compiler.backend; |
| 984 return !instructionType.isNullable | 1017 return !instructionType.isNullable |
| 985 && instructionType.satisfies(backend.jsUInt31Class, classWorld); | 1018 && isInstanceOf(instructionType, backend.jsUInt31Class, classWorld); |
| 986 } | 1019 } |
| 987 | 1020 |
| 988 bool isPositiveInteger(Compiler compiler) { | 1021 bool isPositiveInteger(Compiler compiler) { |
| 989 ClassWorld classWorld = compiler.world; | 1022 ClassWorld classWorld = compiler.world; |
| 990 JavaScriptBackend backend = compiler.backend; | 1023 JavaScriptBackend backend = compiler.backend; |
| 991 return !instructionType.isNullable | 1024 return !instructionType.isNullable && |
| 992 && instructionType.satisfies(backend.jsPositiveIntClass, classWorld); | 1025 isInstanceOf(instructionType, backend.jsPositiveIntClass, classWorld); |
| 993 } | 1026 } |
| 994 | 1027 |
| 995 bool isPositiveIntegerOrNull(Compiler compiler) { | 1028 bool isPositiveIntegerOrNull(Compiler compiler) { |
| 996 ClassWorld classWorld = compiler.world; | 1029 ClassWorld classWorld = compiler.world; |
| 997 JavaScriptBackend backend = compiler.backend; | 1030 JavaScriptBackend backend = compiler.backend; |
| 998 return instructionType.satisfies(backend.jsPositiveIntClass, classWorld); | 1031 return isInstanceOf( |
| 1032 instructionType, backend.jsPositiveIntClass, classWorld); |
| 999 } | 1033 } |
| 1000 | 1034 |
| 1001 bool isIntegerOrNull(Compiler compiler) { | 1035 bool isIntegerOrNull(Compiler compiler) { |
| 1002 ClassWorld classWorld = compiler.world; | 1036 ClassWorld classWorld = compiler.world; |
| 1003 return instructionType.containsOnlyInt(classWorld); | 1037 return instructionType.containsOnlyInt(classWorld); |
| 1004 } | 1038 } |
| 1005 | 1039 |
| 1006 bool isNumber(Compiler compiler) { | 1040 bool isNumber(Compiler compiler) { |
| 1007 ClassWorld classWorld = compiler.world; | 1041 ClassWorld classWorld = compiler.world; |
| 1008 return instructionType.containsOnlyNum(classWorld) | 1042 return instructionType.containsOnlyNum(classWorld) |
| (...skipping 2279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3288 class HDynamicType extends HRuntimeType { | 3322 class HDynamicType extends HRuntimeType { |
| 3289 HDynamicType(DynamicType dartType, TypeMask instructionType) | 3323 HDynamicType(DynamicType dartType, TypeMask instructionType) |
| 3290 : super(const <HInstruction>[], dartType, instructionType); | 3324 : super(const <HInstruction>[], dartType, instructionType); |
| 3291 | 3325 |
| 3292 accept(HVisitor visitor) => visitor.visitDynamicType(this); | 3326 accept(HVisitor visitor) => visitor.visitDynamicType(this); |
| 3293 | 3327 |
| 3294 int typeCode() => HInstruction.DYNAMIC_TYPE_TYPECODE; | 3328 int typeCode() => HInstruction.DYNAMIC_TYPE_TYPECODE; |
| 3295 | 3329 |
| 3296 bool typeEquals(HInstruction other) => other is HDynamicType; | 3330 bool typeEquals(HInstruction other) => other is HDynamicType; |
| 3297 } | 3331 } |
| OLD | NEW |