| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <vector> | 5 #include <vector> |
| 6 | 6 |
| 7 #include "src/crankshaft/hydrogen-types.h" | 7 #include "src/crankshaft/hydrogen-types.h" |
| 8 #include "src/factory.h" | 8 #include "src/factory.h" |
| 9 #include "src/heap/heap.h" | 9 #include "src/heap/heap.h" |
| 10 #include "src/isolate.h" | 10 #include "src/isolate.h" |
| 11 // FIXME(mstarzinger, marja): This is weird, but required because of the missing | 11 // FIXME(mstarzinger, marja): This is weird, but required because of the missing |
| 12 // (disallowed) include: src/factory.h -> src/objects-inl.h | 12 // (disallowed) include: src/factory.h -> src/objects-inl.h |
| 13 #include "src/ast/ast-types.h" |
| 13 #include "src/objects-inl.h" | 14 #include "src/objects-inl.h" |
| 14 #include "src/types.h" | |
| 15 // FIXME(mstarzinger, marja): This is weird, but required because of the missing | 15 // FIXME(mstarzinger, marja): This is weird, but required because of the missing |
| 16 // (disallowed) include: src/type-feedback-vector.h -> | 16 // (disallowed) include: src/type-feedback-vector.h -> |
| 17 // src/type-feedback-vector-inl.h | 17 // src/type-feedback-vector-inl.h |
| 18 #include "src/type-feedback-vector-inl.h" | 18 #include "src/type-feedback-vector-inl.h" |
| 19 #include "test/cctest/ast-types-fuzz.h" |
| 19 #include "test/cctest/cctest.h" | 20 #include "test/cctest/cctest.h" |
| 20 #include "test/cctest/types-fuzz.h" | |
| 21 | 21 |
| 22 using namespace v8::internal; | 22 using namespace v8::internal; |
| 23 | 23 |
| 24 | |
| 25 // Testing auxiliaries (breaking the Type abstraction). | 24 // Testing auxiliaries (breaking the Type abstraction). |
| 26 | 25 |
| 27 | |
| 28 static bool IsInteger(double x) { | 26 static bool IsInteger(double x) { |
| 29 return nearbyint(x) == x && !i::IsMinusZero(x); // Allows for infinities. | 27 return nearbyint(x) == x && !i::IsMinusZero(x); // Allows for infinities. |
| 30 } | 28 } |
| 31 | 29 |
| 32 | |
| 33 static bool IsInteger(i::Object* x) { | 30 static bool IsInteger(i::Object* x) { |
| 34 return x->IsNumber() && IsInteger(x->Number()); | 31 return x->IsNumber() && IsInteger(x->Number()); |
| 35 } | 32 } |
| 36 | 33 |
| 37 | |
| 38 typedef uint32_t bitset; | 34 typedef uint32_t bitset; |
| 39 | 35 |
| 40 struct Tests { | 36 struct Tests { |
| 41 typedef Types::TypeVector::iterator TypeIterator; | 37 typedef Types::TypeVector::iterator TypeIterator; |
| 42 typedef Types::MapVector::iterator MapIterator; | 38 typedef Types::MapVector::iterator MapIterator; |
| 43 typedef Types::ValueVector::iterator ValueIterator; | 39 typedef Types::ValueVector::iterator ValueIterator; |
| 44 | 40 |
| 45 Isolate* isolate; | 41 Isolate* isolate; |
| 46 HandleScope scope; | 42 HandleScope scope; |
| 47 Zone zone; | 43 Zone zone; |
| 48 Types T; | 44 Types T; |
| 49 | 45 |
| 50 Tests() | 46 Tests() |
| 51 : isolate(CcTest::InitIsolateOnce()), | 47 : isolate(CcTest::InitIsolateOnce()), |
| 52 scope(isolate), | 48 scope(isolate), |
| 53 zone(isolate->allocator()), | 49 zone(isolate->allocator()), |
| 54 T(&zone, isolate, isolate->random_number_generator()) {} | 50 T(&zone, isolate, isolate->random_number_generator()) {} |
| 55 | 51 |
| 56 bool IsBitset(Type* type) { return type->IsBitsetForTesting(); } | 52 bool IsBitset(AstType* type) { return type->IsBitsetForTesting(); } |
| 57 bool IsUnion(Type* type) { return type->IsUnionForTesting(); } | 53 bool IsUnion(AstType* type) { return type->IsUnionForTesting(); } |
| 58 BitsetType::bitset AsBitset(Type* type) { return type->AsBitsetForTesting(); } | 54 AstBitsetType::bitset AsBitset(AstType* type) { |
| 59 UnionType* AsUnion(Type* type) { return type->AsUnionForTesting(); } | 55 return type->AsBitsetForTesting(); |
| 56 } |
| 57 AstUnionType* AsUnion(AstType* type) { return type->AsUnionForTesting(); } |
| 60 | 58 |
| 61 bool Equal(Type* type1, Type* type2) { | 59 bool Equal(AstType* type1, AstType* type2) { |
| 62 return type1->Equals(type2) && | 60 return type1->Equals(type2) && |
| 63 this->IsBitset(type1) == this->IsBitset(type2) && | 61 this->IsBitset(type1) == this->IsBitset(type2) && |
| 64 this->IsUnion(type1) == this->IsUnion(type2) && | 62 this->IsUnion(type1) == this->IsUnion(type2) && |
| 65 type1->NumClasses() == type2->NumClasses() && | 63 type1->NumClasses() == type2->NumClasses() && |
| 66 type1->NumConstants() == type2->NumConstants() && | 64 type1->NumConstants() == type2->NumConstants() && |
| 67 (!this->IsBitset(type1) || | 65 (!this->IsBitset(type1) || |
| 68 this->AsBitset(type1) == this->AsBitset(type2)) && | 66 this->AsBitset(type1) == this->AsBitset(type2)) && |
| 69 (!this->IsUnion(type1) || | 67 (!this->IsUnion(type1) || |
| 70 this->AsUnion(type1)->LengthForTesting() == | 68 this->AsUnion(type1)->LengthForTesting() == |
| 71 this->AsUnion(type2)->LengthForTesting()); | 69 this->AsUnion(type2)->LengthForTesting()); |
| 72 } | 70 } |
| 73 | 71 |
| 74 void CheckEqual(Type* type1, Type* type2) { CHECK(Equal(type1, type2)); } | 72 void CheckEqual(AstType* type1, AstType* type2) { |
| 73 CHECK(Equal(type1, type2)); |
| 74 } |
| 75 | 75 |
| 76 void CheckSub(Type* type1, Type* type2) { | 76 void CheckSub(AstType* type1, AstType* type2) { |
| 77 CHECK(type1->Is(type2)); | 77 CHECK(type1->Is(type2)); |
| 78 CHECK(!type2->Is(type1)); | 78 CHECK(!type2->Is(type1)); |
| 79 if (this->IsBitset(type1) && this->IsBitset(type2)) { | 79 if (this->IsBitset(type1) && this->IsBitset(type2)) { |
| 80 CHECK(this->AsBitset(type1) != this->AsBitset(type2)); | 80 CHECK(this->AsBitset(type1) != this->AsBitset(type2)); |
| 81 } | 81 } |
| 82 } | 82 } |
| 83 | 83 |
| 84 void CheckSubOrEqual(Type* type1, Type* type2) { | 84 void CheckSubOrEqual(AstType* type1, AstType* type2) { |
| 85 CHECK(type1->Is(type2)); | 85 CHECK(type1->Is(type2)); |
| 86 if (this->IsBitset(type1) && this->IsBitset(type2)) { | 86 if (this->IsBitset(type1) && this->IsBitset(type2)) { |
| 87 CHECK((this->AsBitset(type1) | this->AsBitset(type2)) | 87 CHECK((this->AsBitset(type1) | this->AsBitset(type2)) == |
| 88 == this->AsBitset(type2)); | 88 this->AsBitset(type2)); |
| 89 } | 89 } |
| 90 } | 90 } |
| 91 | 91 |
| 92 void CheckUnordered(Type* type1, Type* type2) { | 92 void CheckUnordered(AstType* type1, AstType* type2) { |
| 93 CHECK(!type1->Is(type2)); | 93 CHECK(!type1->Is(type2)); |
| 94 CHECK(!type2->Is(type1)); | 94 CHECK(!type2->Is(type1)); |
| 95 if (this->IsBitset(type1) && this->IsBitset(type2)) { | 95 if (this->IsBitset(type1) && this->IsBitset(type2)) { |
| 96 CHECK(this->AsBitset(type1) != this->AsBitset(type2)); | 96 CHECK(this->AsBitset(type1) != this->AsBitset(type2)); |
| 97 } | 97 } |
| 98 } | 98 } |
| 99 | 99 |
| 100 void CheckOverlap(Type* type1, Type* type2) { | 100 void CheckOverlap(AstType* type1, AstType* type2) { |
| 101 CHECK(type1->Maybe(type2)); | 101 CHECK(type1->Maybe(type2)); |
| 102 CHECK(type2->Maybe(type1)); | 102 CHECK(type2->Maybe(type1)); |
| 103 } | 103 } |
| 104 | 104 |
| 105 void CheckDisjoint(Type* type1, Type* type2) { | 105 void CheckDisjoint(AstType* type1, AstType* type2) { |
| 106 CHECK(!type1->Is(type2)); | 106 CHECK(!type1->Is(type2)); |
| 107 CHECK(!type2->Is(type1)); | 107 CHECK(!type2->Is(type1)); |
| 108 CHECK(!type1->Maybe(type2)); | 108 CHECK(!type1->Maybe(type2)); |
| 109 CHECK(!type2->Maybe(type1)); | 109 CHECK(!type2->Maybe(type1)); |
| 110 } | 110 } |
| 111 | 111 |
| 112 void IsSomeType() { | 112 void IsSomeType() { |
| 113 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 113 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 114 Type* t = *it; | 114 AstType* t = *it; |
| 115 CHECK(1 == | 115 CHECK(1 == |
| 116 this->IsBitset(t) + t->IsClass() + t->IsConstant() + t->IsRange() + | 116 this->IsBitset(t) + t->IsClass() + t->IsConstant() + t->IsRange() + |
| 117 this->IsUnion(t) + t->IsArray() + t->IsFunction() + t->IsContext()); | 117 this->IsUnion(t) + t->IsArray() + t->IsFunction() + |
| 118 t->IsContext()); |
| 118 } | 119 } |
| 119 } | 120 } |
| 120 | 121 |
| 121 void Bitset() { | 122 void Bitset() { |
| 122 // None and Any are bitsets. | 123 // None and Any are bitsets. |
| 123 CHECK(this->IsBitset(T.None)); | 124 CHECK(this->IsBitset(T.None)); |
| 124 CHECK(this->IsBitset(T.Any)); | 125 CHECK(this->IsBitset(T.Any)); |
| 125 | 126 |
| 126 CHECK(bitset(0) == this->AsBitset(T.None)); | 127 CHECK(bitset(0) == this->AsBitset(T.None)); |
| 127 CHECK(bitset(0xfffffffeu) == this->AsBitset(T.Any)); | 128 CHECK(bitset(0xfffffffeu) == this->AsBitset(T.Any)); |
| 128 | 129 |
| 129 // Union(T1, T2) is bitset for bitsets T1,T2 | 130 // Union(T1, T2) is bitset for bitsets T1,T2 |
| 130 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 131 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 131 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 132 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 132 Type* type1 = *it1; | 133 AstType* type1 = *it1; |
| 133 Type* type2 = *it2; | 134 AstType* type2 = *it2; |
| 134 Type* union12 = T.Union(type1, type2); | 135 AstType* union12 = T.Union(type1, type2); |
| 135 CHECK(!(this->IsBitset(type1) && this->IsBitset(type2)) || | 136 CHECK(!(this->IsBitset(type1) && this->IsBitset(type2)) || |
| 136 this->IsBitset(union12)); | 137 this->IsBitset(union12)); |
| 137 } | 138 } |
| 138 } | 139 } |
| 139 | 140 |
| 140 // Intersect(T1, T2) is bitset for bitsets T1,T2 | 141 // Intersect(T1, T2) is bitset for bitsets T1,T2 |
| 141 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 142 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 142 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 143 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 143 Type* type1 = *it1; | 144 AstType* type1 = *it1; |
| 144 Type* type2 = *it2; | 145 AstType* type2 = *it2; |
| 145 Type* intersect12 = T.Intersect(type1, type2); | 146 AstType* intersect12 = T.Intersect(type1, type2); |
| 146 CHECK(!(this->IsBitset(type1) && this->IsBitset(type2)) || | 147 CHECK(!(this->IsBitset(type1) && this->IsBitset(type2)) || |
| 147 this->IsBitset(intersect12)); | 148 this->IsBitset(intersect12)); |
| 148 } | 149 } |
| 149 } | 150 } |
| 150 | 151 |
| 151 // Union(T1, T2) is bitset if T2 is bitset and T1->Is(T2) | 152 // Union(T1, T2) is bitset if T2 is bitset and T1->Is(T2) |
| 152 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 153 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 153 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 154 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 154 Type* type1 = *it1; | 155 AstType* type1 = *it1; |
| 155 Type* type2 = *it2; | 156 AstType* type2 = *it2; |
| 156 Type* union12 = T.Union(type1, type2); | 157 AstType* union12 = T.Union(type1, type2); |
| 157 CHECK(!(this->IsBitset(type2) && type1->Is(type2)) || | 158 CHECK(!(this->IsBitset(type2) && type1->Is(type2)) || |
| 158 this->IsBitset(union12)); | 159 this->IsBitset(union12)); |
| 159 } | 160 } |
| 160 } | 161 } |
| 161 | 162 |
| 162 // Union(T1, T2) is bitwise disjunction for bitsets T1,T2 | 163 // Union(T1, T2) is bitwise disjunction for bitsets T1,T2 |
| 163 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 164 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 164 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 165 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 165 Type* type1 = *it1; | 166 AstType* type1 = *it1; |
| 166 Type* type2 = *it2; | 167 AstType* type2 = *it2; |
| 167 Type* union12 = T.Union(type1, type2); | 168 AstType* union12 = T.Union(type1, type2); |
| 168 if (this->IsBitset(type1) && this->IsBitset(type2)) { | 169 if (this->IsBitset(type1) && this->IsBitset(type2)) { |
| 169 CHECK( | 170 CHECK((this->AsBitset(type1) | this->AsBitset(type2)) == |
| 170 (this->AsBitset(type1) | this->AsBitset(type2)) == | 171 this->AsBitset(union12)); |
| 171 this->AsBitset(union12)); | |
| 172 } | 172 } |
| 173 } | 173 } |
| 174 } | 174 } |
| 175 | 175 |
| 176 // Intersect(T1, T2) is bitwise conjunction for bitsets T1,T2 (modulo None) | 176 // Intersect(T1, T2) is bitwise conjunction for bitsets T1,T2 (modulo None) |
| 177 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 177 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 178 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 178 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 179 Type* type1 = *it1; | 179 AstType* type1 = *it1; |
| 180 Type* type2 = *it2; | 180 AstType* type2 = *it2; |
| 181 if (this->IsBitset(type1) && this->IsBitset(type2)) { | 181 if (this->IsBitset(type1) && this->IsBitset(type2)) { |
| 182 Type* intersect12 = T.Intersect(type1, type2); | 182 AstType* intersect12 = T.Intersect(type1, type2); |
| 183 bitset bits = this->AsBitset(type1) & this->AsBitset(type2); | 183 bitset bits = this->AsBitset(type1) & this->AsBitset(type2); |
| 184 CHECK(bits == this->AsBitset(intersect12)); | 184 CHECK(bits == this->AsBitset(intersect12)); |
| 185 } | 185 } |
| 186 } | 186 } |
| 187 } | 187 } |
| 188 } | 188 } |
| 189 | 189 |
| 190 void PointwiseRepresentation() { | 190 void PointwiseRepresentation() { |
| 191 // Check we can decompose type into semantics and representation and | 191 // Check we can decompose type into semantics and representation and |
| 192 // then compose it back to get an equivalent type. | 192 // then compose it back to get an equivalent type. |
| 193 int counter = 0; | 193 int counter = 0; |
| 194 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 194 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 195 counter++; | 195 counter++; |
| 196 printf("Counter: %i\n", counter); | 196 printf("Counter: %i\n", counter); |
| 197 fflush(stdout); | 197 fflush(stdout); |
| 198 Type* type1 = *it1; | 198 AstType* type1 = *it1; |
| 199 Type* representation = T.Representation(type1); | 199 AstType* representation = T.Representation(type1); |
| 200 Type* semantic = T.Semantic(type1); | 200 AstType* semantic = T.Semantic(type1); |
| 201 Type* composed = T.Union(representation, semantic); | 201 AstType* composed = T.Union(representation, semantic); |
| 202 CHECK(type1->Equals(composed)); | 202 CHECK(type1->Equals(composed)); |
| 203 } | 203 } |
| 204 | 204 |
| 205 // Pointwiseness of Union. | 205 // Pointwiseness of Union. |
| 206 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 206 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 207 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 207 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 208 Type* type1 = *it1; | 208 AstType* type1 = *it1; |
| 209 Type* type2 = *it2; | 209 AstType* type2 = *it2; |
| 210 Type* representation1 = T.Representation(type1); | 210 AstType* representation1 = T.Representation(type1); |
| 211 Type* semantic1 = T.Semantic(type1); | 211 AstType* semantic1 = T.Semantic(type1); |
| 212 Type* representation2 = T.Representation(type2); | 212 AstType* representation2 = T.Representation(type2); |
| 213 Type* semantic2 = T.Semantic(type2); | 213 AstType* semantic2 = T.Semantic(type2); |
| 214 Type* direct_union = T.Union(type1, type2); | 214 AstType* direct_union = T.Union(type1, type2); |
| 215 Type* representation_union = T.Union(representation1, representation2); | 215 AstType* representation_union = |
| 216 Type* semantic_union = T.Union(semantic1, semantic2); | 216 T.Union(representation1, representation2); |
| 217 Type* composed_union = T.Union(representation_union, semantic_union); | 217 AstType* semantic_union = T.Union(semantic1, semantic2); |
| 218 AstType* composed_union = T.Union(representation_union, semantic_union); |
| 218 CHECK(direct_union->Equals(composed_union)); | 219 CHECK(direct_union->Equals(composed_union)); |
| 219 } | 220 } |
| 220 } | 221 } |
| 221 | 222 |
| 222 // Pointwiseness of Intersect. | 223 // Pointwiseness of Intersect. |
| 223 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 224 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 224 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 225 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 225 Type* type1 = *it1; | 226 AstType* type1 = *it1; |
| 226 Type* type2 = *it2; | 227 AstType* type2 = *it2; |
| 227 Type* representation1 = T.Representation(type1); | 228 AstType* representation1 = T.Representation(type1); |
| 228 Type* semantic1 = T.Semantic(type1); | 229 AstType* semantic1 = T.Semantic(type1); |
| 229 Type* representation2 = T.Representation(type2); | 230 AstType* representation2 = T.Representation(type2); |
| 230 Type* semantic2 = T.Semantic(type2); | 231 AstType* semantic2 = T.Semantic(type2); |
| 231 Type* direct_intersection = T.Intersect(type1, type2); | 232 AstType* direct_intersection = T.Intersect(type1, type2); |
| 232 Type* representation_intersection = | 233 AstType* representation_intersection = |
| 233 T.Intersect(representation1, representation2); | 234 T.Intersect(representation1, representation2); |
| 234 Type* semantic_intersection = T.Intersect(semantic1, semantic2); | 235 AstType* semantic_intersection = T.Intersect(semantic1, semantic2); |
| 235 Type* composed_intersection = | 236 AstType* composed_intersection = |
| 236 T.Union(representation_intersection, semantic_intersection); | 237 T.Union(representation_intersection, semantic_intersection); |
| 237 CHECK(direct_intersection->Equals(composed_intersection)); | 238 CHECK(direct_intersection->Equals(composed_intersection)); |
| 238 } | 239 } |
| 239 } | 240 } |
| 240 | 241 |
| 241 // Pointwiseness of Is. | 242 // Pointwiseness of Is. |
| 242 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 243 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 243 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 244 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 244 Type* type1 = *it1; | 245 AstType* type1 = *it1; |
| 245 Type* type2 = *it2; | 246 AstType* type2 = *it2; |
| 246 Type* representation1 = T.Representation(type1); | 247 AstType* representation1 = T.Representation(type1); |
| 247 Type* semantic1 = T.Semantic(type1); | 248 AstType* semantic1 = T.Semantic(type1); |
| 248 Type* representation2 = T.Representation(type2); | 249 AstType* representation2 = T.Representation(type2); |
| 249 Type* semantic2 = T.Semantic(type2); | 250 AstType* semantic2 = T.Semantic(type2); |
| 250 bool representation_is = representation1->Is(representation2); | 251 bool representation_is = representation1->Is(representation2); |
| 251 bool semantic_is = semantic1->Is(semantic2); | 252 bool semantic_is = semantic1->Is(semantic2); |
| 252 bool direct_is = type1->Is(type2); | 253 bool direct_is = type1->Is(type2); |
| 253 CHECK(direct_is == (semantic_is && representation_is)); | 254 CHECK(direct_is == (semantic_is && representation_is)); |
| 254 } | 255 } |
| 255 } | 256 } |
| 256 } | 257 } |
| 257 | 258 |
| 258 void Class() { | 259 void Class() { |
| 259 // Constructor | 260 // Constructor |
| 260 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { | 261 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { |
| 261 Handle<i::Map> map = *mt; | 262 Handle<i::Map> map = *mt; |
| 262 Type* type = T.Class(map); | 263 AstType* type = T.Class(map); |
| 263 CHECK(type->IsClass()); | 264 CHECK(type->IsClass()); |
| 264 } | 265 } |
| 265 | 266 |
| 266 // Map attribute | 267 // Map attribute |
| 267 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { | 268 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { |
| 268 Handle<i::Map> map = *mt; | 269 Handle<i::Map> map = *mt; |
| 269 Type* type = T.Class(map); | 270 AstType* type = T.Class(map); |
| 270 CHECK(*map == *type->AsClass()->Map()); | 271 CHECK(*map == *type->AsClass()->Map()); |
| 271 } | 272 } |
| 272 | 273 |
| 273 // Functionality & Injectivity: Class(M1) = Class(M2) iff M1 = M2 | 274 // Functionality & Injectivity: Class(M1) = Class(M2) iff M1 = M2 |
| 274 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) { | 275 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) { |
| 275 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) { | 276 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) { |
| 276 Handle<i::Map> map1 = *mt1; | 277 Handle<i::Map> map1 = *mt1; |
| 277 Handle<i::Map> map2 = *mt2; | 278 Handle<i::Map> map2 = *mt2; |
| 278 Type* type1 = T.Class(map1); | 279 AstType* type1 = T.Class(map1); |
| 279 Type* type2 = T.Class(map2); | 280 AstType* type2 = T.Class(map2); |
| 280 CHECK(Equal(type1, type2) == (*map1 == *map2)); | 281 CHECK(Equal(type1, type2) == (*map1 == *map2)); |
| 281 } | 282 } |
| 282 } | 283 } |
| 283 } | 284 } |
| 284 | 285 |
| 285 void Constant() { | 286 void Constant() { |
| 286 // Constructor | 287 // Constructor |
| 287 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 288 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
| 288 Handle<i::Object> value = *vt; | 289 Handle<i::Object> value = *vt; |
| 289 Type* type = T.Constant(value); | 290 AstType* type = T.Constant(value); |
| 290 CHECK(type->IsConstant()); | 291 CHECK(type->IsConstant()); |
| 291 } | 292 } |
| 292 | 293 |
| 293 // Value attribute | 294 // Value attribute |
| 294 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 295 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
| 295 Handle<i::Object> value = *vt; | 296 Handle<i::Object> value = *vt; |
| 296 Type* type = T.Constant(value); | 297 AstType* type = T.Constant(value); |
| 297 CHECK(*value == *type->AsConstant()->Value()); | 298 CHECK(*value == *type->AsConstant()->Value()); |
| 298 } | 299 } |
| 299 | 300 |
| 300 // Functionality & Injectivity: Constant(V1) = Constant(V2) iff V1 = V2 | 301 // Functionality & Injectivity: Constant(V1) = Constant(V2) iff V1 = V2 |
| 301 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) { | 302 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) { |
| 302 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) { | 303 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) { |
| 303 Handle<i::Object> value1 = *vt1; | 304 Handle<i::Object> value1 = *vt1; |
| 304 Handle<i::Object> value2 = *vt2; | 305 Handle<i::Object> value2 = *vt2; |
| 305 Type* type1 = T.Constant(value1); | 306 AstType* type1 = T.Constant(value1); |
| 306 Type* type2 = T.Constant(value2); | 307 AstType* type2 = T.Constant(value2); |
| 307 CHECK(Equal(type1, type2) == (*value1 == *value2)); | 308 CHECK(Equal(type1, type2) == (*value1 == *value2)); |
| 308 } | 309 } |
| 309 } | 310 } |
| 310 | 311 |
| 311 // Typing of numbers | 312 // Typing of numbers |
| 312 Factory* fac = isolate->factory(); | 313 Factory* fac = isolate->factory(); |
| 313 CHECK(T.Constant(fac->NewNumber(0))->Is(T.UnsignedSmall)); | 314 CHECK(T.Constant(fac->NewNumber(0))->Is(T.UnsignedSmall)); |
| 314 CHECK(T.Constant(fac->NewNumber(1))->Is(T.UnsignedSmall)); | 315 CHECK(T.Constant(fac->NewNumber(1))->Is(T.UnsignedSmall)); |
| 315 CHECK(T.Constant(fac->NewNumber(0x3fffffff))->Is(T.UnsignedSmall)); | 316 CHECK(T.Constant(fac->NewNumber(0x3fffffff))->Is(T.UnsignedSmall)); |
| 316 CHECK(T.Constant(fac->NewNumber(-1))->Is(T.Negative31)); | 317 CHECK(T.Constant(fac->NewNumber(-1))->Is(T.Negative31)); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 343 CHECK(T.Constant(fac->NewNumber(0xffffffffu + 1.0))->Is(T.PlainNumber)); | 344 CHECK(T.Constant(fac->NewNumber(0xffffffffu + 1.0))->Is(T.PlainNumber)); |
| 344 CHECK(!T.Constant(fac->NewNumber(0xffffffffu + 1.0))->Is(T.Integral32)); | 345 CHECK(!T.Constant(fac->NewNumber(0xffffffffu + 1.0))->Is(T.Integral32)); |
| 345 CHECK(T.Constant(fac->NewNumber(-0x7fffffff - 2.0))->Is(T.PlainNumber)); | 346 CHECK(T.Constant(fac->NewNumber(-0x7fffffff - 2.0))->Is(T.PlainNumber)); |
| 346 CHECK(!T.Constant(fac->NewNumber(-0x7fffffff - 2.0))->Is(T.Integral32)); | 347 CHECK(!T.Constant(fac->NewNumber(-0x7fffffff - 2.0))->Is(T.Integral32)); |
| 347 CHECK(T.Constant(fac->NewNumber(0.1))->Is(T.PlainNumber)); | 348 CHECK(T.Constant(fac->NewNumber(0.1))->Is(T.PlainNumber)); |
| 348 CHECK(!T.Constant(fac->NewNumber(0.1))->Is(T.Integral32)); | 349 CHECK(!T.Constant(fac->NewNumber(0.1))->Is(T.Integral32)); |
| 349 CHECK(T.Constant(fac->NewNumber(-10.1))->Is(T.PlainNumber)); | 350 CHECK(T.Constant(fac->NewNumber(-10.1))->Is(T.PlainNumber)); |
| 350 CHECK(!T.Constant(fac->NewNumber(-10.1))->Is(T.Integral32)); | 351 CHECK(!T.Constant(fac->NewNumber(-10.1))->Is(T.Integral32)); |
| 351 CHECK(T.Constant(fac->NewNumber(10e60))->Is(T.PlainNumber)); | 352 CHECK(T.Constant(fac->NewNumber(10e60))->Is(T.PlainNumber)); |
| 352 CHECK(!T.Constant(fac->NewNumber(10e60))->Is(T.Integral32)); | 353 CHECK(!T.Constant(fac->NewNumber(10e60))->Is(T.Integral32)); |
| 353 CHECK(T.Constant(fac->NewNumber(-1.0*0.0))->Is(T.MinusZero)); | 354 CHECK(T.Constant(fac->NewNumber(-1.0 * 0.0))->Is(T.MinusZero)); |
| 354 CHECK(T.Constant(fac->NewNumber(std::numeric_limits<double>::quiet_NaN())) | 355 CHECK(T.Constant(fac->NewNumber(std::numeric_limits<double>::quiet_NaN())) |
| 355 ->Is(T.NaN)); | 356 ->Is(T.NaN)); |
| 356 CHECK(T.Constant(fac->NewNumber(V8_INFINITY))->Is(T.PlainNumber)); | 357 CHECK(T.Constant(fac->NewNumber(V8_INFINITY))->Is(T.PlainNumber)); |
| 357 CHECK(!T.Constant(fac->NewNumber(V8_INFINITY))->Is(T.Integral32)); | 358 CHECK(!T.Constant(fac->NewNumber(V8_INFINITY))->Is(T.Integral32)); |
| 358 CHECK(T.Constant(fac->NewNumber(-V8_INFINITY))->Is(T.PlainNumber)); | 359 CHECK(T.Constant(fac->NewNumber(-V8_INFINITY))->Is(T.PlainNumber)); |
| 359 CHECK(!T.Constant(fac->NewNumber(-V8_INFINITY))->Is(T.Integral32)); | 360 CHECK(!T.Constant(fac->NewNumber(-V8_INFINITY))->Is(T.Integral32)); |
| 360 } | 361 } |
| 361 | 362 |
| 362 void Range() { | 363 void Range() { |
| 363 // Constructor | 364 // Constructor |
| 364 for (ValueIterator i = T.integers.begin(); i != T.integers.end(); ++i) { | 365 for (ValueIterator i = T.integers.begin(); i != T.integers.end(); ++i) { |
| 365 for (ValueIterator j = T.integers.begin(); j != T.integers.end(); ++j) { | 366 for (ValueIterator j = T.integers.begin(); j != T.integers.end(); ++j) { |
| 366 double min = (*i)->Number(); | 367 double min = (*i)->Number(); |
| 367 double max = (*j)->Number(); | 368 double max = (*j)->Number(); |
| 368 if (min > max) std::swap(min, max); | 369 if (min > max) std::swap(min, max); |
| 369 Type* type = T.Range(min, max); | 370 AstType* type = T.Range(min, max); |
| 370 CHECK(type->IsRange()); | 371 CHECK(type->IsRange()); |
| 371 } | 372 } |
| 372 } | 373 } |
| 373 | 374 |
| 374 // Range attributes | 375 // Range attributes |
| 375 for (ValueIterator i = T.integers.begin(); i != T.integers.end(); ++i) { | 376 for (ValueIterator i = T.integers.begin(); i != T.integers.end(); ++i) { |
| 376 for (ValueIterator j = T.integers.begin(); j != T.integers.end(); ++j) { | 377 for (ValueIterator j = T.integers.begin(); j != T.integers.end(); ++j) { |
| 377 double min = (*i)->Number(); | 378 double min = (*i)->Number(); |
| 378 double max = (*j)->Number(); | 379 double max = (*j)->Number(); |
| 379 if (min > max) std::swap(min, max); | 380 if (min > max) std::swap(min, max); |
| 380 Type* type = T.Range(min, max); | 381 AstType* type = T.Range(min, max); |
| 381 CHECK(min == type->AsRange()->Min()); | 382 CHECK(min == type->AsRange()->Min()); |
| 382 CHECK(max == type->AsRange()->Max()); | 383 CHECK(max == type->AsRange()->Max()); |
| 383 } | 384 } |
| 384 } | 385 } |
| 385 | 386 |
| 386 // Functionality & Injectivity: | 387 // Functionality & Injectivity: |
| 387 // Range(min1, max1) = Range(min2, max2) <=> min1 = min2 /\ max1 = max2 | 388 // Range(min1, max1) = Range(min2, max2) <=> min1 = min2 /\ max1 = max2 |
| 388 for (ValueIterator i1 = T.integers.begin(); | 389 for (ValueIterator i1 = T.integers.begin(); i1 != T.integers.end(); ++i1) { |
| 389 i1 != T.integers.end(); ++i1) { | 390 for (ValueIterator j1 = i1; j1 != T.integers.end(); ++j1) { |
| 390 for (ValueIterator j1 = i1; | 391 for (ValueIterator i2 = T.integers.begin(); i2 != T.integers.end(); |
| 391 j1 != T.integers.end(); ++j1) { | 392 ++i2) { |
| 392 for (ValueIterator i2 = T.integers.begin(); | 393 for (ValueIterator j2 = i2; j2 != T.integers.end(); ++j2) { |
| 393 i2 != T.integers.end(); ++i2) { | |
| 394 for (ValueIterator j2 = i2; | |
| 395 j2 != T.integers.end(); ++j2) { | |
| 396 double min1 = (*i1)->Number(); | 394 double min1 = (*i1)->Number(); |
| 397 double max1 = (*j1)->Number(); | 395 double max1 = (*j1)->Number(); |
| 398 double min2 = (*i2)->Number(); | 396 double min2 = (*i2)->Number(); |
| 399 double max2 = (*j2)->Number(); | 397 double max2 = (*j2)->Number(); |
| 400 if (min1 > max1) std::swap(min1, max1); | 398 if (min1 > max1) std::swap(min1, max1); |
| 401 if (min2 > max2) std::swap(min2, max2); | 399 if (min2 > max2) std::swap(min2, max2); |
| 402 Type* type1 = T.Range(min1, max1); | 400 AstType* type1 = T.Range(min1, max1); |
| 403 Type* type2 = T.Range(min2, max2); | 401 AstType* type2 = T.Range(min2, max2); |
| 404 CHECK(Equal(type1, type2) == (min1 == min2 && max1 == max2)); | 402 CHECK(Equal(type1, type2) == (min1 == min2 && max1 == max2)); |
| 405 } | 403 } |
| 406 } | 404 } |
| 407 } | 405 } |
| 408 } | 406 } |
| 409 } | 407 } |
| 410 | 408 |
| 411 void Context() { | 409 void Context() { |
| 412 // Constructor | 410 // Constructor |
| 413 for (int i = 0; i < 20; ++i) { | 411 for (int i = 0; i < 20; ++i) { |
| 414 Type* type = T.Random(); | 412 AstType* type = T.Random(); |
| 415 Type* context = T.Context(type); | 413 AstType* context = T.Context(type); |
| 416 CHECK(context->IsContext()); | 414 CHECK(context->IsContext()); |
| 417 } | 415 } |
| 418 | 416 |
| 419 // Attributes | 417 // Attributes |
| 420 for (int i = 0; i < 20; ++i) { | 418 for (int i = 0; i < 20; ++i) { |
| 421 Type* type = T.Random(); | 419 AstType* type = T.Random(); |
| 422 Type* context = T.Context(type); | 420 AstType* context = T.Context(type); |
| 423 CheckEqual(type, context->AsContext()->Outer()); | 421 CheckEqual(type, context->AsContext()->Outer()); |
| 424 } | 422 } |
| 425 | 423 |
| 426 // Functionality & Injectivity: Context(T1) = Context(T2) iff T1 = T2 | 424 // Functionality & Injectivity: Context(T1) = Context(T2) iff T1 = T2 |
| 427 for (int i = 0; i < 20; ++i) { | 425 for (int i = 0; i < 20; ++i) { |
| 428 for (int j = 0; j < 20; ++j) { | 426 for (int j = 0; j < 20; ++j) { |
| 429 Type* type1 = T.Random(); | 427 AstType* type1 = T.Random(); |
| 430 Type* type2 = T.Random(); | 428 AstType* type2 = T.Random(); |
| 431 Type* context1 = T.Context(type1); | 429 AstType* context1 = T.Context(type1); |
| 432 Type* context2 = T.Context(type2); | 430 AstType* context2 = T.Context(type2); |
| 433 CHECK(Equal(context1, context2) == Equal(type1, type2)); | 431 CHECK(Equal(context1, context2) == Equal(type1, type2)); |
| 434 } | 432 } |
| 435 } | 433 } |
| 436 } | 434 } |
| 437 | 435 |
| 438 void Array() { | 436 void Array() { |
| 439 // Constructor | 437 // Constructor |
| 440 for (int i = 0; i < 20; ++i) { | 438 for (int i = 0; i < 20; ++i) { |
| 441 Type* type = T.Random(); | 439 AstType* type = T.Random(); |
| 442 Type* array = T.Array1(type); | 440 AstType* array = T.Array1(type); |
| 443 CHECK(array->IsArray()); | 441 CHECK(array->IsArray()); |
| 444 } | 442 } |
| 445 | 443 |
| 446 // Attributes | 444 // Attributes |
| 447 for (int i = 0; i < 20; ++i) { | 445 for (int i = 0; i < 20; ++i) { |
| 448 Type* type = T.Random(); | 446 AstType* type = T.Random(); |
| 449 Type* array = T.Array1(type); | 447 AstType* array = T.Array1(type); |
| 450 CheckEqual(type, array->AsArray()->Element()); | 448 CheckEqual(type, array->AsArray()->Element()); |
| 451 } | 449 } |
| 452 | 450 |
| 453 // Functionality & Injectivity: Array(T1) = Array(T2) iff T1 = T2 | 451 // Functionality & Injectivity: Array(T1) = Array(T2) iff T1 = T2 |
| 454 for (int i = 0; i < 20; ++i) { | 452 for (int i = 0; i < 20; ++i) { |
| 455 for (int j = 0; j < 20; ++j) { | 453 for (int j = 0; j < 20; ++j) { |
| 456 Type* type1 = T.Random(); | 454 AstType* type1 = T.Random(); |
| 457 Type* type2 = T.Random(); | 455 AstType* type2 = T.Random(); |
| 458 Type* array1 = T.Array1(type1); | 456 AstType* array1 = T.Array1(type1); |
| 459 Type* array2 = T.Array1(type2); | 457 AstType* array2 = T.Array1(type2); |
| 460 CHECK(Equal(array1, array2) == Equal(type1, type2)); | 458 CHECK(Equal(array1, array2) == Equal(type1, type2)); |
| 461 } | 459 } |
| 462 } | 460 } |
| 463 } | 461 } |
| 464 | 462 |
| 465 void Function() { | 463 void Function() { |
| 466 // Constructors | 464 // Constructors |
| 467 for (int i = 0; i < 20; ++i) { | 465 for (int i = 0; i < 20; ++i) { |
| 468 for (int j = 0; j < 20; ++j) { | 466 for (int j = 0; j < 20; ++j) { |
| 469 for (int k = 0; k < 20; ++k) { | 467 for (int k = 0; k < 20; ++k) { |
| 470 Type* type1 = T.Random(); | 468 AstType* type1 = T.Random(); |
| 471 Type* type2 = T.Random(); | 469 AstType* type2 = T.Random(); |
| 472 Type* type3 = T.Random(); | 470 AstType* type3 = T.Random(); |
| 473 Type* function0 = T.Function0(type1, type2); | 471 AstType* function0 = T.Function0(type1, type2); |
| 474 Type* function1 = T.Function1(type1, type2, type3); | 472 AstType* function1 = T.Function1(type1, type2, type3); |
| 475 Type* function2 = T.Function2(type1, type2, type3); | 473 AstType* function2 = T.Function2(type1, type2, type3); |
| 476 CHECK(function0->IsFunction()); | 474 CHECK(function0->IsFunction()); |
| 477 CHECK(function1->IsFunction()); | 475 CHECK(function1->IsFunction()); |
| 478 CHECK(function2->IsFunction()); | 476 CHECK(function2->IsFunction()); |
| 479 } | 477 } |
| 480 } | 478 } |
| 481 } | 479 } |
| 482 | 480 |
| 483 // Attributes | 481 // Attributes |
| 484 for (int i = 0; i < 20; ++i) { | 482 for (int i = 0; i < 20; ++i) { |
| 485 for (int j = 0; j < 20; ++j) { | 483 for (int j = 0; j < 20; ++j) { |
| 486 for (int k = 0; k < 20; ++k) { | 484 for (int k = 0; k < 20; ++k) { |
| 487 Type* type1 = T.Random(); | 485 AstType* type1 = T.Random(); |
| 488 Type* type2 = T.Random(); | 486 AstType* type2 = T.Random(); |
| 489 Type* type3 = T.Random(); | 487 AstType* type3 = T.Random(); |
| 490 Type* function0 = T.Function0(type1, type2); | 488 AstType* function0 = T.Function0(type1, type2); |
| 491 Type* function1 = T.Function1(type1, type2, type3); | 489 AstType* function1 = T.Function1(type1, type2, type3); |
| 492 Type* function2 = T.Function2(type1, type2, type3); | 490 AstType* function2 = T.Function2(type1, type2, type3); |
| 493 CHECK_EQ(0, function0->AsFunction()->Arity()); | 491 CHECK_EQ(0, function0->AsFunction()->Arity()); |
| 494 CHECK_EQ(1, function1->AsFunction()->Arity()); | 492 CHECK_EQ(1, function1->AsFunction()->Arity()); |
| 495 CHECK_EQ(2, function2->AsFunction()->Arity()); | 493 CHECK_EQ(2, function2->AsFunction()->Arity()); |
| 496 CheckEqual(type1, function0->AsFunction()->Result()); | 494 CheckEqual(type1, function0->AsFunction()->Result()); |
| 497 CheckEqual(type1, function1->AsFunction()->Result()); | 495 CheckEqual(type1, function1->AsFunction()->Result()); |
| 498 CheckEqual(type1, function2->AsFunction()->Result()); | 496 CheckEqual(type1, function2->AsFunction()->Result()); |
| 499 CheckEqual(type2, function0->AsFunction()->Receiver()); | 497 CheckEqual(type2, function0->AsFunction()->Receiver()); |
| 500 CheckEqual(type2, function1->AsFunction()->Receiver()); | 498 CheckEqual(type2, function1->AsFunction()->Receiver()); |
| 501 CheckEqual(T.Any, function2->AsFunction()->Receiver()); | 499 CheckEqual(T.Any, function2->AsFunction()->Receiver()); |
| 502 CheckEqual(type3, function1->AsFunction()->Parameter(0)); | 500 CheckEqual(type3, function1->AsFunction()->Parameter(0)); |
| 503 CheckEqual(type2, function2->AsFunction()->Parameter(0)); | 501 CheckEqual(type2, function2->AsFunction()->Parameter(0)); |
| 504 CheckEqual(type3, function2->AsFunction()->Parameter(1)); | 502 CheckEqual(type3, function2->AsFunction()->Parameter(1)); |
| 505 } | 503 } |
| 506 } | 504 } |
| 507 } | 505 } |
| 508 | 506 |
| 509 // Functionality & Injectivity: Function(Ts1) = Function(Ts2) iff Ts1 = Ts2 | 507 // Functionality & Injectivity: Function(Ts1) = Function(Ts2) iff Ts1 = Ts2 |
| 510 for (int i = 0; i < 20; ++i) { | 508 for (int i = 0; i < 20; ++i) { |
| 511 for (int j = 0; j < 20; ++j) { | 509 for (int j = 0; j < 20; ++j) { |
| 512 for (int k = 0; k < 20; ++k) { | 510 for (int k = 0; k < 20; ++k) { |
| 513 Type* type1 = T.Random(); | 511 AstType* type1 = T.Random(); |
| 514 Type* type2 = T.Random(); | 512 AstType* type2 = T.Random(); |
| 515 Type* type3 = T.Random(); | 513 AstType* type3 = T.Random(); |
| 516 Type* function01 = T.Function0(type1, type2); | 514 AstType* function01 = T.Function0(type1, type2); |
| 517 Type* function02 = T.Function0(type1, type3); | 515 AstType* function02 = T.Function0(type1, type3); |
| 518 Type* function03 = T.Function0(type3, type2); | 516 AstType* function03 = T.Function0(type3, type2); |
| 519 Type* function11 = T.Function1(type1, type2, type2); | 517 AstType* function11 = T.Function1(type1, type2, type2); |
| 520 Type* function12 = T.Function1(type1, type2, type3); | 518 AstType* function12 = T.Function1(type1, type2, type3); |
| 521 Type* function21 = T.Function2(type1, type2, type2); | 519 AstType* function21 = T.Function2(type1, type2, type2); |
| 522 Type* function22 = T.Function2(type1, type2, type3); | 520 AstType* function22 = T.Function2(type1, type2, type3); |
| 523 Type* function23 = T.Function2(type1, type3, type2); | 521 AstType* function23 = T.Function2(type1, type3, type2); |
| 524 CHECK(Equal(function01, function02) == Equal(type2, type3)); | 522 CHECK(Equal(function01, function02) == Equal(type2, type3)); |
| 525 CHECK(Equal(function01, function03) == Equal(type1, type3)); | 523 CHECK(Equal(function01, function03) == Equal(type1, type3)); |
| 526 CHECK(Equal(function11, function12) == Equal(type2, type3)); | 524 CHECK(Equal(function11, function12) == Equal(type2, type3)); |
| 527 CHECK(Equal(function21, function22) == Equal(type2, type3)); | 525 CHECK(Equal(function21, function22) == Equal(type2, type3)); |
| 528 CHECK(Equal(function21, function23) == Equal(type2, type3)); | 526 CHECK(Equal(function21, function23) == Equal(type2, type3)); |
| 529 } | 527 } |
| 530 } | 528 } |
| 531 } | 529 } |
| 532 } | 530 } |
| 533 | 531 |
| 534 void Of() { | 532 void Of() { |
| 535 // Constant(V)->Is(Of(V)) | 533 // Constant(V)->Is(Of(V)) |
| 536 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 534 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
| 537 Handle<i::Object> value = *vt; | 535 Handle<i::Object> value = *vt; |
| 538 Type* const_type = T.Constant(value); | 536 AstType* const_type = T.Constant(value); |
| 539 Type* of_type = T.Of(value); | 537 AstType* of_type = T.Of(value); |
| 540 CHECK(const_type->Is(of_type)); | 538 CHECK(const_type->Is(of_type)); |
| 541 } | 539 } |
| 542 | 540 |
| 543 // If Of(V)->Is(T), then Constant(V)->Is(T) | 541 // If Of(V)->Is(T), then Constant(V)->Is(T) |
| 544 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 542 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
| 545 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 543 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 546 Handle<i::Object> value = *vt; | 544 Handle<i::Object> value = *vt; |
| 547 Type* type = *it; | 545 AstType* type = *it; |
| 548 Type* const_type = T.Constant(value); | 546 AstType* const_type = T.Constant(value); |
| 549 Type* of_type = T.Of(value); | 547 AstType* of_type = T.Of(value); |
| 550 CHECK(!of_type->Is(type) || const_type->Is(type)); | 548 CHECK(!of_type->Is(type) || const_type->Is(type)); |
| 551 } | 549 } |
| 552 } | 550 } |
| 553 | 551 |
| 554 // If Constant(V)->Is(T), then Of(V)->Is(T) or T->Maybe(Constant(V)) | 552 // If Constant(V)->Is(T), then Of(V)->Is(T) or T->Maybe(Constant(V)) |
| 555 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 553 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
| 556 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 554 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 557 Handle<i::Object> value = *vt; | 555 Handle<i::Object> value = *vt; |
| 558 Type* type = *it; | 556 AstType* type = *it; |
| 559 Type* const_type = T.Constant(value); | 557 AstType* const_type = T.Constant(value); |
| 560 Type* of_type = T.Of(value); | 558 AstType* of_type = T.Of(value); |
| 561 CHECK(!const_type->Is(type) || | 559 CHECK(!const_type->Is(type) || of_type->Is(type) || |
| 562 of_type->Is(type) || type->Maybe(const_type)); | 560 type->Maybe(const_type)); |
| 563 } | 561 } |
| 564 } | 562 } |
| 565 } | 563 } |
| 566 | 564 |
| 567 void NowOf() { | 565 void NowOf() { |
| 568 // Constant(V)->NowIs(NowOf(V)) | 566 // Constant(V)->NowIs(NowOf(V)) |
| 569 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 567 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
| 570 Handle<i::Object> value = *vt; | 568 Handle<i::Object> value = *vt; |
| 571 Type* const_type = T.Constant(value); | 569 AstType* const_type = T.Constant(value); |
| 572 Type* nowof_type = T.NowOf(value); | 570 AstType* nowof_type = T.NowOf(value); |
| 573 CHECK(const_type->NowIs(nowof_type)); | 571 CHECK(const_type->NowIs(nowof_type)); |
| 574 } | 572 } |
| 575 | 573 |
| 576 // NowOf(V)->Is(Of(V)) | 574 // NowOf(V)->Is(Of(V)) |
| 577 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 575 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
| 578 Handle<i::Object> value = *vt; | 576 Handle<i::Object> value = *vt; |
| 579 Type* nowof_type = T.NowOf(value); | 577 AstType* nowof_type = T.NowOf(value); |
| 580 Type* of_type = T.Of(value); | 578 AstType* of_type = T.Of(value); |
| 581 CHECK(nowof_type->Is(of_type)); | 579 CHECK(nowof_type->Is(of_type)); |
| 582 } | 580 } |
| 583 | 581 |
| 584 // If NowOf(V)->NowIs(T), then Constant(V)->NowIs(T) | 582 // If NowOf(V)->NowIs(T), then Constant(V)->NowIs(T) |
| 585 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 583 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
| 586 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 584 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 587 Handle<i::Object> value = *vt; | 585 Handle<i::Object> value = *vt; |
| 588 Type* type = *it; | 586 AstType* type = *it; |
| 589 Type* const_type = T.Constant(value); | 587 AstType* const_type = T.Constant(value); |
| 590 Type* nowof_type = T.NowOf(value); | 588 AstType* nowof_type = T.NowOf(value); |
| 591 CHECK(!nowof_type->NowIs(type) || const_type->NowIs(type)); | 589 CHECK(!nowof_type->NowIs(type) || const_type->NowIs(type)); |
| 592 } | 590 } |
| 593 } | 591 } |
| 594 | 592 |
| 595 // If Constant(V)->NowIs(T), | 593 // If Constant(V)->NowIs(T), |
| 596 // then NowOf(V)->NowIs(T) or T->Maybe(Constant(V)) | 594 // then NowOf(V)->NowIs(T) or T->Maybe(Constant(V)) |
| 597 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 595 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
| 598 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 596 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 599 Handle<i::Object> value = *vt; | 597 Handle<i::Object> value = *vt; |
| 600 Type* type = *it; | 598 AstType* type = *it; |
| 601 Type* const_type = T.Constant(value); | 599 AstType* const_type = T.Constant(value); |
| 602 Type* nowof_type = T.NowOf(value); | 600 AstType* nowof_type = T.NowOf(value); |
| 603 CHECK(!const_type->NowIs(type) || | 601 CHECK(!const_type->NowIs(type) || nowof_type->NowIs(type) || |
| 604 nowof_type->NowIs(type) || type->Maybe(const_type)); | 602 type->Maybe(const_type)); |
| 605 } | 603 } |
| 606 } | 604 } |
| 607 | 605 |
| 608 // If Constant(V)->Is(T), | 606 // If Constant(V)->Is(T), |
| 609 // then NowOf(V)->Is(T) or T->Maybe(Constant(V)) | 607 // then NowOf(V)->Is(T) or T->Maybe(Constant(V)) |
| 610 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 608 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
| 611 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 609 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 612 Handle<i::Object> value = *vt; | 610 Handle<i::Object> value = *vt; |
| 613 Type* type = *it; | 611 AstType* type = *it; |
| 614 Type* const_type = T.Constant(value); | 612 AstType* const_type = T.Constant(value); |
| 615 Type* nowof_type = T.NowOf(value); | 613 AstType* nowof_type = T.NowOf(value); |
| 616 CHECK(!const_type->Is(type) || | 614 CHECK(!const_type->Is(type) || nowof_type->Is(type) || |
| 617 nowof_type->Is(type) || type->Maybe(const_type)); | 615 type->Maybe(const_type)); |
| 618 } | 616 } |
| 619 } | 617 } |
| 620 } | 618 } |
| 621 | 619 |
| 622 void MinMax() { | 620 void MinMax() { |
| 623 // If b is regular numeric bitset, then Range(b->Min(), b->Max())->Is(b). | 621 // If b is regular numeric bitset, then Range(b->Min(), b->Max())->Is(b). |
| 624 // TODO(neis): Need to ignore representation for this to be true. | 622 // TODO(neis): Need to ignore representation for this to be true. |
| 625 /* | 623 /* |
| 626 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 624 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 627 Type* type = *it; | 625 AstType* type = *it; |
| 628 if (this->IsBitset(type) && type->Is(T.Number) && | 626 if (this->IsBitset(type) && type->Is(T.Number) && |
| 629 !type->Is(T.None) && !type->Is(T.NaN)) { | 627 !type->Is(T.None) && !type->Is(T.NaN)) { |
| 630 Type* range = T.Range( | 628 AstType* range = T.Range( |
| 631 isolate->factory()->NewNumber(type->Min()), | 629 isolate->factory()->NewNumber(type->Min()), |
| 632 isolate->factory()->NewNumber(type->Max())); | 630 isolate->factory()->NewNumber(type->Max())); |
| 633 CHECK(range->Is(type)); | 631 CHECK(range->Is(type)); |
| 634 } | 632 } |
| 635 } | 633 } |
| 636 */ | 634 */ |
| 637 | 635 |
| 638 // If b is regular numeric bitset, then b->Min() and b->Max() are integers. | 636 // If b is regular numeric bitset, then b->Min() and b->Max() are integers. |
| 639 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 637 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 640 Type* type = *it; | 638 AstType* type = *it; |
| 641 if (this->IsBitset(type) && type->Is(T.Number) && !type->Is(T.NaN)) { | 639 if (this->IsBitset(type) && type->Is(T.Number) && !type->Is(T.NaN)) { |
| 642 CHECK(IsInteger(type->Min()) && IsInteger(type->Max())); | 640 CHECK(IsInteger(type->Min()) && IsInteger(type->Max())); |
| 643 } | 641 } |
| 644 } | 642 } |
| 645 | 643 |
| 646 // If b1 and b2 are regular numeric bitsets with b1->Is(b2), then | 644 // If b1 and b2 are regular numeric bitsets with b1->Is(b2), then |
| 647 // b1->Min() >= b2->Min() and b1->Max() <= b2->Max(). | 645 // b1->Min() >= b2->Min() and b1->Max() <= b2->Max(). |
| 648 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 646 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 649 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 647 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 650 Type* type1 = *it1; | 648 AstType* type1 = *it1; |
| 651 Type* type2 = *it2; | 649 AstType* type2 = *it2; |
| 652 if (this->IsBitset(type1) && type1->Is(type2) && type2->Is(T.Number) && | 650 if (this->IsBitset(type1) && type1->Is(type2) && type2->Is(T.Number) && |
| 653 !type1->Is(T.NaN) && !type2->Is(T.NaN)) { | 651 !type1->Is(T.NaN) && !type2->Is(T.NaN)) { |
| 654 CHECK(type1->Min() >= type2->Min()); | 652 CHECK(type1->Min() >= type2->Min()); |
| 655 CHECK(type1->Max() <= type2->Max()); | 653 CHECK(type1->Max() <= type2->Max()); |
| 656 } | 654 } |
| 657 } | 655 } |
| 658 } | 656 } |
| 659 | 657 |
| 660 // Lub(Range(x,y))->Min() <= x and y <= Lub(Range(x,y))->Max() | 658 // Lub(Range(x,y))->Min() <= x and y <= Lub(Range(x,y))->Max() |
| 661 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 659 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 662 Type* type = *it; | 660 AstType* type = *it; |
| 663 if (type->IsRange()) { | 661 if (type->IsRange()) { |
| 664 Type* lub = BitsetType::NewForTesting(BitsetType::Lub(type)); | 662 AstType* lub = AstBitsetType::NewForTesting(AstBitsetType::Lub(type)); |
| 665 CHECK(lub->Min() <= type->Min() && type->Max() <= lub->Max()); | 663 CHECK(lub->Min() <= type->Min() && type->Max() <= lub->Max()); |
| 666 } | 664 } |
| 667 } | 665 } |
| 668 | 666 |
| 669 // Rangification: If T->Is(Range(-inf,+inf)) and T is inhabited, then | 667 // Rangification: If T->Is(Range(-inf,+inf)) and T is inhabited, then |
| 670 // T->Is(Range(T->Min(), T->Max())). | 668 // T->Is(Range(T->Min(), T->Max())). |
| 671 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 669 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 672 Type* type = *it; | 670 AstType* type = *it; |
| 673 CHECK(!type->Is(T.Integer) || !type->IsInhabited() || | 671 CHECK(!type->Is(T.Integer) || !type->IsInhabited() || |
| 674 type->Is(T.Range(type->Min(), type->Max()))); | 672 type->Is(T.Range(type->Min(), type->Max()))); |
| 675 } | 673 } |
| 676 } | 674 } |
| 677 | 675 |
| 678 void BitsetGlb() { | 676 void BitsetGlb() { |
| 679 // Lower: (T->BitsetGlb())->Is(T) | 677 // Lower: (T->BitsetGlb())->Is(T) |
| 680 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 678 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 681 Type* type = *it; | 679 AstType* type = *it; |
| 682 Type* glb = BitsetType::NewForTesting(BitsetType::Glb(type)); | 680 AstType* glb = AstBitsetType::NewForTesting(AstBitsetType::Glb(type)); |
| 683 CHECK(glb->Is(type)); | 681 CHECK(glb->Is(type)); |
| 684 } | 682 } |
| 685 | 683 |
| 686 // Greatest: If T1->IsBitset() and T1->Is(T2), then T1->Is(T2->BitsetGlb()) | 684 // Greatest: If T1->IsBitset() and T1->Is(T2), then T1->Is(T2->BitsetGlb()) |
| 687 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 685 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 688 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 686 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 689 Type* type1 = *it1; | 687 AstType* type1 = *it1; |
| 690 Type* type2 = *it2; | 688 AstType* type2 = *it2; |
| 691 Type* glb2 = BitsetType::NewForTesting(BitsetType::Glb(type2)); | 689 AstType* glb2 = AstBitsetType::NewForTesting(AstBitsetType::Glb(type2)); |
| 692 CHECK(!this->IsBitset(type1) || !type1->Is(type2) || type1->Is(glb2)); | 690 CHECK(!this->IsBitset(type1) || !type1->Is(type2) || type1->Is(glb2)); |
| 693 } | 691 } |
| 694 } | 692 } |
| 695 | 693 |
| 696 // Monotonicity: T1->Is(T2) implies (T1->BitsetGlb())->Is(T2->BitsetGlb()) | 694 // Monotonicity: T1->Is(T2) implies (T1->BitsetGlb())->Is(T2->BitsetGlb()) |
| 697 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 695 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 698 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 696 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 699 Type* type1 = *it1; | 697 AstType* type1 = *it1; |
| 700 Type* type2 = *it2; | 698 AstType* type2 = *it2; |
| 701 Type* glb1 = BitsetType::NewForTesting(BitsetType::Glb(type1)); | 699 AstType* glb1 = AstBitsetType::NewForTesting(AstBitsetType::Glb(type1)); |
| 702 Type* glb2 = BitsetType::NewForTesting(BitsetType::Glb(type2)); | 700 AstType* glb2 = AstBitsetType::NewForTesting(AstBitsetType::Glb(type2)); |
| 703 CHECK(!type1->Is(type2) || glb1->Is(glb2)); | 701 CHECK(!type1->Is(type2) || glb1->Is(glb2)); |
| 704 } | 702 } |
| 705 } | 703 } |
| 706 } | 704 } |
| 707 | 705 |
| 708 void BitsetLub() { | 706 void BitsetLub() { |
| 709 // Upper: T->Is(T->BitsetLub()) | 707 // Upper: T->Is(T->BitsetLub()) |
| 710 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 708 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 711 Type* type = *it; | 709 AstType* type = *it; |
| 712 Type* lub = BitsetType::NewForTesting(BitsetType::Lub(type)); | 710 AstType* lub = AstBitsetType::NewForTesting(AstBitsetType::Lub(type)); |
| 713 CHECK(type->Is(lub)); | 711 CHECK(type->Is(lub)); |
| 714 } | 712 } |
| 715 | 713 |
| 716 // Least: If T2->IsBitset() and T1->Is(T2), then (T1->BitsetLub())->Is(T2) | 714 // Least: If T2->IsBitset() and T1->Is(T2), then (T1->BitsetLub())->Is(T2) |
| 717 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 715 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 718 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 716 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 719 Type* type1 = *it1; | 717 AstType* type1 = *it1; |
| 720 Type* type2 = *it2; | 718 AstType* type2 = *it2; |
| 721 Type* lub1 = BitsetType::NewForTesting(BitsetType::Lub(type1)); | 719 AstType* lub1 = AstBitsetType::NewForTesting(AstBitsetType::Lub(type1)); |
| 722 CHECK(!this->IsBitset(type2) || !type1->Is(type2) || lub1->Is(type2)); | 720 CHECK(!this->IsBitset(type2) || !type1->Is(type2) || lub1->Is(type2)); |
| 723 } | 721 } |
| 724 } | 722 } |
| 725 | 723 |
| 726 // Monotonicity: T1->Is(T2) implies (T1->BitsetLub())->Is(T2->BitsetLub()) | 724 // Monotonicity: T1->Is(T2) implies (T1->BitsetLub())->Is(T2->BitsetLub()) |
| 727 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 725 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 728 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 726 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 729 Type* type1 = *it1; | 727 AstType* type1 = *it1; |
| 730 Type* type2 = *it2; | 728 AstType* type2 = *it2; |
| 731 Type* lub1 = BitsetType::NewForTesting(BitsetType::Lub(type1)); | 729 AstType* lub1 = AstBitsetType::NewForTesting(AstBitsetType::Lub(type1)); |
| 732 Type* lub2 = BitsetType::NewForTesting(BitsetType::Lub(type2)); | 730 AstType* lub2 = AstBitsetType::NewForTesting(AstBitsetType::Lub(type2)); |
| 733 CHECK(!type1->Is(type2) || lub1->Is(lub2)); | 731 CHECK(!type1->Is(type2) || lub1->Is(lub2)); |
| 734 } | 732 } |
| 735 } | 733 } |
| 736 } | 734 } |
| 737 | 735 |
| 738 void Is1() { | 736 void Is1() { |
| 739 // Least Element (Bottom): None->Is(T) | 737 // Least Element (Bottom): None->Is(T) |
| 740 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 738 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 741 Type* type = *it; | 739 AstType* type = *it; |
| 742 CHECK(T.None->Is(type)); | 740 CHECK(T.None->Is(type)); |
| 743 } | 741 } |
| 744 | 742 |
| 745 // Greatest Element (Top): T->Is(Any) | 743 // Greatest Element (Top): T->Is(Any) |
| 746 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 744 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 747 Type* type = *it; | 745 AstType* type = *it; |
| 748 CHECK(type->Is(T.Any)); | 746 CHECK(type->Is(T.Any)); |
| 749 } | 747 } |
| 750 | 748 |
| 751 // Bottom Uniqueness: T->Is(None) implies T = None | 749 // Bottom Uniqueness: T->Is(None) implies T = None |
| 752 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 750 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 753 Type* type = *it; | 751 AstType* type = *it; |
| 754 if (type->Is(T.None)) CheckEqual(type, T.None); | 752 if (type->Is(T.None)) CheckEqual(type, T.None); |
| 755 } | 753 } |
| 756 | 754 |
| 757 // Top Uniqueness: Any->Is(T) implies T = Any | 755 // Top Uniqueness: Any->Is(T) implies T = Any |
| 758 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 756 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 759 Type* type = *it; | 757 AstType* type = *it; |
| 760 if (T.Any->Is(type)) CheckEqual(type, T.Any); | 758 if (T.Any->Is(type)) CheckEqual(type, T.Any); |
| 761 } | 759 } |
| 762 | 760 |
| 763 // Reflexivity: T->Is(T) | 761 // Reflexivity: T->Is(T) |
| 764 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 762 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 765 Type* type = *it; | 763 AstType* type = *it; |
| 766 CHECK(type->Is(type)); | 764 CHECK(type->Is(type)); |
| 767 } | 765 } |
| 768 | 766 |
| 769 // Transitivity: T1->Is(T2) and T2->Is(T3) implies T1->Is(T3) | 767 // Transitivity: T1->Is(T2) and T2->Is(T3) implies T1->Is(T3) |
| 770 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 768 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 771 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 769 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 772 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { | 770 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { |
| 773 Type* type1 = *it1; | 771 AstType* type1 = *it1; |
| 774 Type* type2 = *it2; | 772 AstType* type2 = *it2; |
| 775 Type* type3 = *it3; | 773 AstType* type3 = *it3; |
| 776 CHECK(!(type1->Is(type2) && type2->Is(type3)) || type1->Is(type3)); | 774 CHECK(!(type1->Is(type2) && type2->Is(type3)) || type1->Is(type3)); |
| 777 } | 775 } |
| 778 } | 776 } |
| 779 } | 777 } |
| 780 | 778 |
| 781 // Antisymmetry: T1->Is(T2) and T2->Is(T1) iff T1 = T2 | 779 // Antisymmetry: T1->Is(T2) and T2->Is(T1) iff T1 = T2 |
| 782 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 780 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 783 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 781 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 784 Type* type1 = *it1; | 782 AstType* type1 = *it1; |
| 785 Type* type2 = *it2; | 783 AstType* type2 = *it2; |
| 786 CHECK((type1->Is(type2) && type2->Is(type1)) == Equal(type1, type2)); | 784 CHECK((type1->Is(type2) && type2->Is(type1)) == Equal(type1, type2)); |
| 787 } | 785 } |
| 788 } | 786 } |
| 789 | 787 |
| 790 // (In-)Compatibilities. | 788 // (In-)Compatibilities. |
| 791 for (TypeIterator i = T.types.begin(); i != T.types.end(); ++i) { | 789 for (TypeIterator i = T.types.begin(); i != T.types.end(); ++i) { |
| 792 for (TypeIterator j = T.types.begin(); j != T.types.end(); ++j) { | 790 for (TypeIterator j = T.types.begin(); j != T.types.end(); ++j) { |
| 793 Type* type1 = *i; | 791 AstType* type1 = *i; |
| 794 Type* type2 = *j; | 792 AstType* type2 = *j; |
| 795 CHECK(!type1->Is(type2) || this->IsBitset(type2) || | 793 CHECK(!type1->Is(type2) || this->IsBitset(type2) || |
| 796 this->IsUnion(type2) || this->IsUnion(type1) || | 794 this->IsUnion(type2) || this->IsUnion(type1) || |
| 797 (type1->IsClass() && type2->IsClass()) || | 795 (type1->IsClass() && type2->IsClass()) || |
| 798 (type1->IsConstant() && type2->IsConstant()) || | 796 (type1->IsConstant() && type2->IsConstant()) || |
| 799 (type1->IsConstant() && type2->IsRange()) || | 797 (type1->IsConstant() && type2->IsRange()) || |
| 800 (this->IsBitset(type1) && type2->IsRange()) || | 798 (this->IsBitset(type1) && type2->IsRange()) || |
| 801 (type1->IsRange() && type2->IsRange()) || | 799 (type1->IsRange() && type2->IsRange()) || |
| 802 (type1->IsContext() && type2->IsContext()) || | 800 (type1->IsContext() && type2->IsContext()) || |
| 803 (type1->IsArray() && type2->IsArray()) || | 801 (type1->IsArray() && type2->IsArray()) || |
| 804 (type1->IsFunction() && type2->IsFunction()) || | 802 (type1->IsFunction() && type2->IsFunction()) || |
| 805 !type1->IsInhabited()); | 803 !type1->IsInhabited()); |
| 806 } | 804 } |
| 807 } | 805 } |
| 808 } | 806 } |
| 809 | 807 |
| 810 void Is2() { | 808 void Is2() { |
| 811 // Class(M1)->Is(Class(M2)) iff M1 = M2 | 809 // Class(M1)->Is(Class(M2)) iff M1 = M2 |
| 812 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) { | 810 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) { |
| 813 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) { | 811 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) { |
| 814 Handle<i::Map> map1 = *mt1; | 812 Handle<i::Map> map1 = *mt1; |
| 815 Handle<i::Map> map2 = *mt2; | 813 Handle<i::Map> map2 = *mt2; |
| 816 Type* class_type1 = T.Class(map1); | 814 AstType* class_type1 = T.Class(map1); |
| 817 Type* class_type2 = T.Class(map2); | 815 AstType* class_type2 = T.Class(map2); |
| 818 CHECK(class_type1->Is(class_type2) == (*map1 == *map2)); | 816 CHECK(class_type1->Is(class_type2) == (*map1 == *map2)); |
| 819 } | 817 } |
| 820 } | 818 } |
| 821 | 819 |
| 822 // Range(X1, Y1)->Is(Range(X2, Y2)) iff X1 >= X2 /\ Y1 <= Y2 | 820 // Range(X1, Y1)->Is(Range(X2, Y2)) iff X1 >= X2 /\ Y1 <= Y2 |
| 823 for (ValueIterator i1 = T.integers.begin(); | 821 for (ValueIterator i1 = T.integers.begin(); i1 != T.integers.end(); ++i1) { |
| 824 i1 != T.integers.end(); ++i1) { | 822 for (ValueIterator j1 = i1; j1 != T.integers.end(); ++j1) { |
| 825 for (ValueIterator j1 = i1; | 823 for (ValueIterator i2 = T.integers.begin(); i2 != T.integers.end(); |
| 826 j1 != T.integers.end(); ++j1) { | 824 ++i2) { |
| 827 for (ValueIterator i2 = T.integers.begin(); | 825 for (ValueIterator j2 = i2; j2 != T.integers.end(); ++j2) { |
| 828 i2 != T.integers.end(); ++i2) { | |
| 829 for (ValueIterator j2 = i2; | |
| 830 j2 != T.integers.end(); ++j2) { | |
| 831 double min1 = (*i1)->Number(); | 826 double min1 = (*i1)->Number(); |
| 832 double max1 = (*j1)->Number(); | 827 double max1 = (*j1)->Number(); |
| 833 double min2 = (*i2)->Number(); | 828 double min2 = (*i2)->Number(); |
| 834 double max2 = (*j2)->Number(); | 829 double max2 = (*j2)->Number(); |
| 835 if (min1 > max1) std::swap(min1, max1); | 830 if (min1 > max1) std::swap(min1, max1); |
| 836 if (min2 > max2) std::swap(min2, max2); | 831 if (min2 > max2) std::swap(min2, max2); |
| 837 Type* type1 = T.Range(min1, max1); | 832 AstType* type1 = T.Range(min1, max1); |
| 838 Type* type2 = T.Range(min2, max2); | 833 AstType* type2 = T.Range(min2, max2); |
| 839 CHECK(type1->Is(type2) == (min1 >= min2 && max1 <= max2)); | 834 CHECK(type1->Is(type2) == (min1 >= min2 && max1 <= max2)); |
| 840 } | 835 } |
| 841 } | 836 } |
| 842 } | 837 } |
| 843 } | 838 } |
| 844 | 839 |
| 845 // Constant(V1)->Is(Constant(V2)) iff V1 = V2 | 840 // Constant(V1)->Is(Constant(V2)) iff V1 = V2 |
| 846 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) { | 841 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) { |
| 847 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) { | 842 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) { |
| 848 Handle<i::Object> value1 = *vt1; | 843 Handle<i::Object> value1 = *vt1; |
| 849 Handle<i::Object> value2 = *vt2; | 844 Handle<i::Object> value2 = *vt2; |
| 850 Type* const_type1 = T.Constant(value1); | 845 AstType* const_type1 = T.Constant(value1); |
| 851 Type* const_type2 = T.Constant(value2); | 846 AstType* const_type2 = T.Constant(value2); |
| 852 CHECK(const_type1->Is(const_type2) == (*value1 == *value2)); | 847 CHECK(const_type1->Is(const_type2) == (*value1 == *value2)); |
| 853 } | 848 } |
| 854 } | 849 } |
| 855 | 850 |
| 856 // Context(T1)->Is(Context(T2)) iff T1 = T2 | 851 // Context(T1)->Is(Context(T2)) iff T1 = T2 |
| 857 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 852 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 858 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 853 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 859 Type* outer1 = *it1; | 854 AstType* outer1 = *it1; |
| 860 Type* outer2 = *it2; | 855 AstType* outer2 = *it2; |
| 861 Type* type1 = T.Context(outer1); | 856 AstType* type1 = T.Context(outer1); |
| 862 Type* type2 = T.Context(outer2); | 857 AstType* type2 = T.Context(outer2); |
| 863 CHECK(type1->Is(type2) == outer1->Equals(outer2)); | 858 CHECK(type1->Is(type2) == outer1->Equals(outer2)); |
| 864 } | 859 } |
| 865 } | 860 } |
| 866 | 861 |
| 867 // Array(T1)->Is(Array(T2)) iff T1 = T2 | 862 // Array(T1)->Is(Array(T2)) iff T1 = T2 |
| 868 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 863 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 869 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 864 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 870 Type* element1 = *it1; | 865 AstType* element1 = *it1; |
| 871 Type* element2 = *it2; | 866 AstType* element2 = *it2; |
| 872 Type* type1 = T.Array1(element1); | 867 AstType* type1 = T.Array1(element1); |
| 873 Type* type2 = T.Array1(element2); | 868 AstType* type2 = T.Array1(element2); |
| 874 CHECK(type1->Is(type2) == element1->Equals(element2)); | 869 CHECK(type1->Is(type2) == element1->Equals(element2)); |
| 875 } | 870 } |
| 876 } | 871 } |
| 877 | 872 |
| 878 // Function0(S1, T1)->Is(Function0(S2, T2)) iff S1 = S2 and T1 = T2 | 873 // Function0(S1, T1)->Is(Function0(S2, T2)) iff S1 = S2 and T1 = T2 |
| 879 for (TypeIterator i = T.types.begin(); i != T.types.end(); ++i) { | 874 for (TypeIterator i = T.types.begin(); i != T.types.end(); ++i) { |
| 880 for (TypeIterator j = T.types.begin(); j != T.types.end(); ++j) { | 875 for (TypeIterator j = T.types.begin(); j != T.types.end(); ++j) { |
| 881 Type* result1 = *i; | 876 AstType* result1 = *i; |
| 882 Type* receiver1 = *j; | 877 AstType* receiver1 = *j; |
| 883 Type* type1 = T.Function0(result1, receiver1); | 878 AstType* type1 = T.Function0(result1, receiver1); |
| 884 Type* result2 = T.Random(); | 879 AstType* result2 = T.Random(); |
| 885 Type* receiver2 = T.Random(); | 880 AstType* receiver2 = T.Random(); |
| 886 Type* type2 = T.Function0(result2, receiver2); | 881 AstType* type2 = T.Function0(result2, receiver2); |
| 887 CHECK(type1->Is(type2) == | 882 CHECK(type1->Is(type2) == |
| 888 (result1->Equals(result2) && receiver1->Equals(receiver2))); | 883 (result1->Equals(result2) && receiver1->Equals(receiver2))); |
| 889 } | 884 } |
| 890 } | 885 } |
| 891 | 886 |
| 892 | |
| 893 // Range-specific subtyping | 887 // Range-specific subtyping |
| 894 | 888 |
| 895 // If IsInteger(v) then Constant(v)->Is(Range(v, v)). | 889 // If IsInteger(v) then Constant(v)->Is(Range(v, v)). |
| 896 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 890 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 897 Type* type = *it; | 891 AstType* type = *it; |
| 898 if (type->IsConstant() && IsInteger(*type->AsConstant()->Value())) { | 892 if (type->IsConstant() && IsInteger(*type->AsConstant()->Value())) { |
| 899 CHECK(type->Is(T.Range(type->AsConstant()->Value()->Number(), | 893 CHECK(type->Is(T.Range(type->AsConstant()->Value()->Number(), |
| 900 type->AsConstant()->Value()->Number()))); | 894 type->AsConstant()->Value()->Number()))); |
| 901 } | 895 } |
| 902 } | 896 } |
| 903 | 897 |
| 904 // If Constant(x)->Is(Range(min,max)) then IsInteger(v) and min <= x <= max. | 898 // If Constant(x)->Is(Range(min,max)) then IsInteger(v) and min <= x <= max. |
| 905 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 899 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 906 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 900 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 907 Type* type1 = *it1; | 901 AstType* type1 = *it1; |
| 908 Type* type2 = *it2; | 902 AstType* type2 = *it2; |
| 909 if (type1->IsConstant() && type2->IsRange() && type1->Is(type2)) { | 903 if (type1->IsConstant() && type2->IsRange() && type1->Is(type2)) { |
| 910 double x = type1->AsConstant()->Value()->Number(); | 904 double x = type1->AsConstant()->Value()->Number(); |
| 911 double min = type2->AsRange()->Min(); | 905 double min = type2->AsRange()->Min(); |
| 912 double max = type2->AsRange()->Max(); | 906 double max = type2->AsRange()->Max(); |
| 913 CHECK(IsInteger(x) && min <= x && x <= max); | 907 CHECK(IsInteger(x) && min <= x && x <= max); |
| 914 } | 908 } |
| 915 } | 909 } |
| 916 } | 910 } |
| 917 | 911 |
| 918 // Lub(Range(x,y))->Is(T.Union(T.Integral32, T.OtherNumber)) | 912 // Lub(Range(x,y))->Is(T.Union(T.Integral32, T.OtherNumber)) |
| 919 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 913 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 920 Type* type = *it; | 914 AstType* type = *it; |
| 921 if (type->IsRange()) { | 915 if (type->IsRange()) { |
| 922 Type* lub = BitsetType::NewForTesting(BitsetType::Lub(type)); | 916 AstType* lub = AstBitsetType::NewForTesting(AstBitsetType::Lub(type)); |
| 923 CHECK(lub->Is(T.PlainNumber)); | 917 CHECK(lub->Is(T.PlainNumber)); |
| 924 } | 918 } |
| 925 } | 919 } |
| 926 | 920 |
| 927 | |
| 928 // Subtyping between concrete basic types | 921 // Subtyping between concrete basic types |
| 929 | 922 |
| 930 CheckUnordered(T.Boolean, T.Null); | 923 CheckUnordered(T.Boolean, T.Null); |
| 931 CheckUnordered(T.Undefined, T.Null); | 924 CheckUnordered(T.Undefined, T.Null); |
| 932 CheckUnordered(T.Boolean, T.Undefined); | 925 CheckUnordered(T.Boolean, T.Undefined); |
| 933 | 926 |
| 934 CheckSub(T.SignedSmall, T.Number); | 927 CheckSub(T.SignedSmall, T.Number); |
| 935 CheckSub(T.Signed32, T.Number); | 928 CheckSub(T.Signed32, T.Number); |
| 936 CheckSubOrEqual(T.SignedSmall, T.Signed32); | 929 CheckSubOrEqual(T.SignedSmall, T.Signed32); |
| 937 CheckUnordered(T.SignedSmall, T.MinusZero); | 930 CheckUnordered(T.SignedSmall, T.MinusZero); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 993 | 986 |
| 994 CheckSub(T.MethodFunction, T.Object); | 987 CheckSub(T.MethodFunction, T.Object); |
| 995 CheckSub(T.NumberFunction1, T.Object); | 988 CheckSub(T.NumberFunction1, T.Object); |
| 996 CheckUnordered(T.SignedFunction1, T.NumberFunction1); | 989 CheckUnordered(T.SignedFunction1, T.NumberFunction1); |
| 997 CheckUnordered(T.NumberFunction1, T.NumberFunction2); | 990 CheckUnordered(T.NumberFunction1, T.NumberFunction2); |
| 998 } | 991 } |
| 999 | 992 |
| 1000 void NowIs() { | 993 void NowIs() { |
| 1001 // Least Element (Bottom): None->NowIs(T) | 994 // Least Element (Bottom): None->NowIs(T) |
| 1002 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 995 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 1003 Type* type = *it; | 996 AstType* type = *it; |
| 1004 CHECK(T.None->NowIs(type)); | 997 CHECK(T.None->NowIs(type)); |
| 1005 } | 998 } |
| 1006 | 999 |
| 1007 // Greatest Element (Top): T->NowIs(Any) | 1000 // Greatest Element (Top): T->NowIs(Any) |
| 1008 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 1001 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 1009 Type* type = *it; | 1002 AstType* type = *it; |
| 1010 CHECK(type->NowIs(T.Any)); | 1003 CHECK(type->NowIs(T.Any)); |
| 1011 } | 1004 } |
| 1012 | 1005 |
| 1013 // Bottom Uniqueness: T->NowIs(None) implies T = None | 1006 // Bottom Uniqueness: T->NowIs(None) implies T = None |
| 1014 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 1007 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 1015 Type* type = *it; | 1008 AstType* type = *it; |
| 1016 if (type->NowIs(T.None)) CheckEqual(type, T.None); | 1009 if (type->NowIs(T.None)) CheckEqual(type, T.None); |
| 1017 } | 1010 } |
| 1018 | 1011 |
| 1019 // Top Uniqueness: Any->NowIs(T) implies T = Any | 1012 // Top Uniqueness: Any->NowIs(T) implies T = Any |
| 1020 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 1013 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 1021 Type* type = *it; | 1014 AstType* type = *it; |
| 1022 if (T.Any->NowIs(type)) CheckEqual(type, T.Any); | 1015 if (T.Any->NowIs(type)) CheckEqual(type, T.Any); |
| 1023 } | 1016 } |
| 1024 | 1017 |
| 1025 // Reflexivity: T->NowIs(T) | 1018 // Reflexivity: T->NowIs(T) |
| 1026 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 1019 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 1027 Type* type = *it; | 1020 AstType* type = *it; |
| 1028 CHECK(type->NowIs(type)); | 1021 CHECK(type->NowIs(type)); |
| 1029 } | 1022 } |
| 1030 | 1023 |
| 1031 // Transitivity: T1->NowIs(T2) and T2->NowIs(T3) implies T1->NowIs(T3) | 1024 // Transitivity: T1->NowIs(T2) and T2->NowIs(T3) implies T1->NowIs(T3) |
| 1032 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 1025 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1033 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 1026 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1034 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { | 1027 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { |
| 1035 Type* type1 = *it1; | 1028 AstType* type1 = *it1; |
| 1036 Type* type2 = *it2; | 1029 AstType* type2 = *it2; |
| 1037 Type* type3 = *it3; | 1030 AstType* type3 = *it3; |
| 1038 CHECK(!(type1->NowIs(type2) && type2->NowIs(type3)) || | 1031 CHECK(!(type1->NowIs(type2) && type2->NowIs(type3)) || |
| 1039 type1->NowIs(type3)); | 1032 type1->NowIs(type3)); |
| 1040 } | 1033 } |
| 1041 } | 1034 } |
| 1042 } | 1035 } |
| 1043 | 1036 |
| 1044 // Antisymmetry: T1->NowIs(T2) and T2->NowIs(T1) iff T1 = T2 | 1037 // Antisymmetry: T1->NowIs(T2) and T2->NowIs(T1) iff T1 = T2 |
| 1045 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 1038 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1046 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 1039 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1047 Type* type1 = *it1; | 1040 AstType* type1 = *it1; |
| 1048 Type* type2 = *it2; | 1041 AstType* type2 = *it2; |
| 1049 CHECK((type1->NowIs(type2) && type2->NowIs(type1)) == | 1042 CHECK((type1->NowIs(type2) && type2->NowIs(type1)) == |
| 1050 Equal(type1, type2)); | 1043 Equal(type1, type2)); |
| 1051 } | 1044 } |
| 1052 } | 1045 } |
| 1053 | 1046 |
| 1054 // T1->Is(T2) implies T1->NowIs(T2) | 1047 // T1->Is(T2) implies T1->NowIs(T2) |
| 1055 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 1048 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1056 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 1049 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1057 Type* type1 = *it1; | 1050 AstType* type1 = *it1; |
| 1058 Type* type2 = *it2; | 1051 AstType* type2 = *it2; |
| 1059 CHECK(!type1->Is(type2) || type1->NowIs(type2)); | 1052 CHECK(!type1->Is(type2) || type1->NowIs(type2)); |
| 1060 } | 1053 } |
| 1061 } | 1054 } |
| 1062 | 1055 |
| 1063 // Constant(V1)->NowIs(Constant(V2)) iff V1 = V2 | 1056 // Constant(V1)->NowIs(Constant(V2)) iff V1 = V2 |
| 1064 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) { | 1057 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) { |
| 1065 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) { | 1058 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) { |
| 1066 Handle<i::Object> value1 = *vt1; | 1059 Handle<i::Object> value1 = *vt1; |
| 1067 Handle<i::Object> value2 = *vt2; | 1060 Handle<i::Object> value2 = *vt2; |
| 1068 Type* const_type1 = T.Constant(value1); | 1061 AstType* const_type1 = T.Constant(value1); |
| 1069 Type* const_type2 = T.Constant(value2); | 1062 AstType* const_type2 = T.Constant(value2); |
| 1070 CHECK(const_type1->NowIs(const_type2) == (*value1 == *value2)); | 1063 CHECK(const_type1->NowIs(const_type2) == (*value1 == *value2)); |
| 1071 } | 1064 } |
| 1072 } | 1065 } |
| 1073 | 1066 |
| 1074 // Class(M1)->NowIs(Class(M2)) iff M1 = M2 | 1067 // Class(M1)->NowIs(Class(M2)) iff M1 = M2 |
| 1075 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) { | 1068 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) { |
| 1076 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) { | 1069 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) { |
| 1077 Handle<i::Map> map1 = *mt1; | 1070 Handle<i::Map> map1 = *mt1; |
| 1078 Handle<i::Map> map2 = *mt2; | 1071 Handle<i::Map> map2 = *mt2; |
| 1079 Type* class_type1 = T.Class(map1); | 1072 AstType* class_type1 = T.Class(map1); |
| 1080 Type* class_type2 = T.Class(map2); | 1073 AstType* class_type2 = T.Class(map2); |
| 1081 CHECK(class_type1->NowIs(class_type2) == (*map1 == *map2)); | 1074 CHECK(class_type1->NowIs(class_type2) == (*map1 == *map2)); |
| 1082 } | 1075 } |
| 1083 } | 1076 } |
| 1084 | 1077 |
| 1085 // Constant(V)->NowIs(Class(M)) iff V has map M | 1078 // Constant(V)->NowIs(Class(M)) iff V has map M |
| 1086 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { | 1079 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { |
| 1087 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 1080 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
| 1088 Handle<i::Map> map = *mt; | 1081 Handle<i::Map> map = *mt; |
| 1089 Handle<i::Object> value = *vt; | 1082 Handle<i::Object> value = *vt; |
| 1090 Type* const_type = T.Constant(value); | 1083 AstType* const_type = T.Constant(value); |
| 1091 Type* class_type = T.Class(map); | 1084 AstType* class_type = T.Class(map); |
| 1092 CHECK((value->IsHeapObject() && | 1085 CHECK((value->IsHeapObject() && |
| 1093 i::HeapObject::cast(*value)->map() == *map) | 1086 i::HeapObject::cast(*value)->map() == *map) == |
| 1094 == const_type->NowIs(class_type)); | 1087 const_type->NowIs(class_type)); |
| 1095 } | 1088 } |
| 1096 } | 1089 } |
| 1097 | 1090 |
| 1098 // Class(M)->NowIs(Constant(V)) never | 1091 // Class(M)->NowIs(Constant(V)) never |
| 1099 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { | 1092 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { |
| 1100 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 1093 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
| 1101 Handle<i::Map> map = *mt; | 1094 Handle<i::Map> map = *mt; |
| 1102 Handle<i::Object> value = *vt; | 1095 Handle<i::Object> value = *vt; |
| 1103 Type* const_type = T.Constant(value); | 1096 AstType* const_type = T.Constant(value); |
| 1104 Type* class_type = T.Class(map); | 1097 AstType* class_type = T.Class(map); |
| 1105 CHECK(!class_type->NowIs(const_type)); | 1098 CHECK(!class_type->NowIs(const_type)); |
| 1106 } | 1099 } |
| 1107 } | 1100 } |
| 1108 } | 1101 } |
| 1109 | 1102 |
| 1110 void Contains() { | 1103 void Contains() { |
| 1111 // T->Contains(V) iff Constant(V)->Is(T) | 1104 // T->Contains(V) iff Constant(V)->Is(T) |
| 1112 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 1105 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 1113 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 1106 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
| 1114 Type* type = *it; | 1107 AstType* type = *it; |
| 1115 Handle<i::Object> value = *vt; | 1108 Handle<i::Object> value = *vt; |
| 1116 Type* const_type = T.Constant(value); | 1109 AstType* const_type = T.Constant(value); |
| 1117 CHECK(type->Contains(value) == const_type->Is(type)); | 1110 CHECK(type->Contains(value) == const_type->Is(type)); |
| 1118 } | 1111 } |
| 1119 } | 1112 } |
| 1120 } | 1113 } |
| 1121 | 1114 |
| 1122 void NowContains() { | 1115 void NowContains() { |
| 1123 // T->NowContains(V) iff Constant(V)->NowIs(T) | 1116 // T->NowContains(V) iff Constant(V)->NowIs(T) |
| 1124 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 1117 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 1125 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 1118 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
| 1126 Type* type = *it; | 1119 AstType* type = *it; |
| 1127 Handle<i::Object> value = *vt; | 1120 Handle<i::Object> value = *vt; |
| 1128 Type* const_type = T.Constant(value); | 1121 AstType* const_type = T.Constant(value); |
| 1129 CHECK(type->NowContains(value) == const_type->NowIs(type)); | 1122 CHECK(type->NowContains(value) == const_type->NowIs(type)); |
| 1130 } | 1123 } |
| 1131 } | 1124 } |
| 1132 | 1125 |
| 1133 // T->Contains(V) implies T->NowContains(V) | 1126 // T->Contains(V) implies T->NowContains(V) |
| 1134 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 1127 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 1135 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 1128 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
| 1136 Type* type = *it; | 1129 AstType* type = *it; |
| 1137 Handle<i::Object> value = *vt; | 1130 Handle<i::Object> value = *vt; |
| 1138 CHECK(!type->Contains(value) || type->NowContains(value)); | 1131 CHECK(!type->Contains(value) || type->NowContains(value)); |
| 1139 } | 1132 } |
| 1140 } | 1133 } |
| 1141 | 1134 |
| 1142 // NowOf(V)->Is(T) implies T->NowContains(V) | 1135 // NowOf(V)->Is(T) implies T->NowContains(V) |
| 1143 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 1136 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 1144 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 1137 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
| 1145 Type* type = *it; | 1138 AstType* type = *it; |
| 1146 Handle<i::Object> value = *vt; | 1139 Handle<i::Object> value = *vt; |
| 1147 Type* nowof_type = T.Of(value); | 1140 AstType* nowof_type = T.Of(value); |
| 1148 CHECK(!nowof_type->NowIs(type) || type->NowContains(value)); | 1141 CHECK(!nowof_type->NowIs(type) || type->NowContains(value)); |
| 1149 } | 1142 } |
| 1150 } | 1143 } |
| 1151 } | 1144 } |
| 1152 | 1145 |
| 1153 void Maybe() { | 1146 void Maybe() { |
| 1154 // T->Maybe(Any) iff T inhabited | 1147 // T->Maybe(Any) iff T inhabited |
| 1155 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 1148 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 1156 Type* type = *it; | 1149 AstType* type = *it; |
| 1157 CHECK(type->Maybe(T.Any) == type->IsInhabited()); | 1150 CHECK(type->Maybe(T.Any) == type->IsInhabited()); |
| 1158 } | 1151 } |
| 1159 | 1152 |
| 1160 // T->Maybe(None) never | 1153 // T->Maybe(None) never |
| 1161 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 1154 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 1162 Type* type = *it; | 1155 AstType* type = *it; |
| 1163 CHECK(!type->Maybe(T.None)); | 1156 CHECK(!type->Maybe(T.None)); |
| 1164 } | 1157 } |
| 1165 | 1158 |
| 1166 // Reflexivity upto Inhabitation: T->Maybe(T) iff T inhabited | 1159 // Reflexivity upto Inhabitation: T->Maybe(T) iff T inhabited |
| 1167 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 1160 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 1168 Type* type = *it; | 1161 AstType* type = *it; |
| 1169 CHECK(type->Maybe(type) == type->IsInhabited()); | 1162 CHECK(type->Maybe(type) == type->IsInhabited()); |
| 1170 } | 1163 } |
| 1171 | 1164 |
| 1172 // Symmetry: T1->Maybe(T2) iff T2->Maybe(T1) | 1165 // Symmetry: T1->Maybe(T2) iff T2->Maybe(T1) |
| 1173 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 1166 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1174 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 1167 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1175 Type* type1 = *it1; | 1168 AstType* type1 = *it1; |
| 1176 Type* type2 = *it2; | 1169 AstType* type2 = *it2; |
| 1177 CHECK(type1->Maybe(type2) == type2->Maybe(type1)); | 1170 CHECK(type1->Maybe(type2) == type2->Maybe(type1)); |
| 1178 } | 1171 } |
| 1179 } | 1172 } |
| 1180 | 1173 |
| 1181 // T1->Maybe(T2) implies T1, T2 inhabited | 1174 // T1->Maybe(T2) implies T1, T2 inhabited |
| 1182 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 1175 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1183 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 1176 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1184 Type* type1 = *it1; | 1177 AstType* type1 = *it1; |
| 1185 Type* type2 = *it2; | 1178 AstType* type2 = *it2; |
| 1186 CHECK(!type1->Maybe(type2) || | 1179 CHECK(!type1->Maybe(type2) || |
| 1187 (type1->IsInhabited() && type2->IsInhabited())); | 1180 (type1->IsInhabited() && type2->IsInhabited())); |
| 1188 } | 1181 } |
| 1189 } | 1182 } |
| 1190 | 1183 |
| 1191 // T1->Maybe(T2) implies Intersect(T1, T2) inhabited | 1184 // T1->Maybe(T2) implies Intersect(T1, T2) inhabited |
| 1192 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 1185 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1193 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 1186 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1194 Type* type1 = *it1; | 1187 AstType* type1 = *it1; |
| 1195 Type* type2 = *it2; | 1188 AstType* type2 = *it2; |
| 1196 Type* intersect12 = T.Intersect(type1, type2); | 1189 AstType* intersect12 = T.Intersect(type1, type2); |
| 1197 CHECK(!type1->Maybe(type2) || intersect12->IsInhabited()); | 1190 CHECK(!type1->Maybe(type2) || intersect12->IsInhabited()); |
| 1198 } | 1191 } |
| 1199 } | 1192 } |
| 1200 | 1193 |
| 1201 // T1->Is(T2) and T1 inhabited implies T1->Maybe(T2) | 1194 // T1->Is(T2) and T1 inhabited implies T1->Maybe(T2) |
| 1202 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 1195 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1203 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 1196 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1204 Type* type1 = *it1; | 1197 AstType* type1 = *it1; |
| 1205 Type* type2 = *it2; | 1198 AstType* type2 = *it2; |
| 1206 CHECK(!(type1->Is(type2) && type1->IsInhabited()) || | 1199 CHECK(!(type1->Is(type2) && type1->IsInhabited()) || |
| 1207 type1->Maybe(type2)); | 1200 type1->Maybe(type2)); |
| 1208 } | 1201 } |
| 1209 } | 1202 } |
| 1210 | 1203 |
| 1211 // Constant(V1)->Maybe(Constant(V2)) iff V1 = V2 | 1204 // Constant(V1)->Maybe(Constant(V2)) iff V1 = V2 |
| 1212 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) { | 1205 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) { |
| 1213 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) { | 1206 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) { |
| 1214 Handle<i::Object> value1 = *vt1; | 1207 Handle<i::Object> value1 = *vt1; |
| 1215 Handle<i::Object> value2 = *vt2; | 1208 Handle<i::Object> value2 = *vt2; |
| 1216 Type* const_type1 = T.Constant(value1); | 1209 AstType* const_type1 = T.Constant(value1); |
| 1217 Type* const_type2 = T.Constant(value2); | 1210 AstType* const_type2 = T.Constant(value2); |
| 1218 CHECK(const_type1->Maybe(const_type2) == (*value1 == *value2)); | 1211 CHECK(const_type1->Maybe(const_type2) == (*value1 == *value2)); |
| 1219 } | 1212 } |
| 1220 } | 1213 } |
| 1221 | 1214 |
| 1222 // Class(M1)->Maybe(Class(M2)) iff M1 = M2 | 1215 // Class(M1)->Maybe(Class(M2)) iff M1 = M2 |
| 1223 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) { | 1216 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) { |
| 1224 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) { | 1217 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) { |
| 1225 Handle<i::Map> map1 = *mt1; | 1218 Handle<i::Map> map1 = *mt1; |
| 1226 Handle<i::Map> map2 = *mt2; | 1219 Handle<i::Map> map2 = *mt2; |
| 1227 Type* class_type1 = T.Class(map1); | 1220 AstType* class_type1 = T.Class(map1); |
| 1228 Type* class_type2 = T.Class(map2); | 1221 AstType* class_type2 = T.Class(map2); |
| 1229 CHECK(class_type1->Maybe(class_type2) == (*map1 == *map2)); | 1222 CHECK(class_type1->Maybe(class_type2) == (*map1 == *map2)); |
| 1230 } | 1223 } |
| 1231 } | 1224 } |
| 1232 | 1225 |
| 1233 // Constant(V)->Maybe(Class(M)) never | 1226 // Constant(V)->Maybe(Class(M)) never |
| 1234 // This does NOT hold! | 1227 // This does NOT hold! |
| 1235 /* | 1228 /* |
| 1236 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { | 1229 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { |
| 1237 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 1230 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
| 1238 Handle<i::Map> map = *mt; | 1231 Handle<i::Map> map = *mt; |
| 1239 Handle<i::Object> value = *vt; | 1232 Handle<i::Object> value = *vt; |
| 1240 Type* const_type = T.Constant(value); | 1233 AstType* const_type = T.Constant(value); |
| 1241 Type* class_type = T.Class(map); | 1234 AstType* class_type = T.Class(map); |
| 1242 CHECK(!const_type->Maybe(class_type)); | 1235 CHECK(!const_type->Maybe(class_type)); |
| 1243 } | 1236 } |
| 1244 } | 1237 } |
| 1245 */ | 1238 */ |
| 1246 | 1239 |
| 1247 // Class(M)->Maybe(Constant(V)) never | 1240 // Class(M)->Maybe(Constant(V)) never |
| 1248 // This does NOT hold! | 1241 // This does NOT hold! |
| 1249 /* | 1242 /* |
| 1250 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { | 1243 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { |
| 1251 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 1244 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
| 1252 Handle<i::Map> map = *mt; | 1245 Handle<i::Map> map = *mt; |
| 1253 Handle<i::Object> value = *vt; | 1246 Handle<i::Object> value = *vt; |
| 1254 Type* const_type = T.Constant(value); | 1247 AstType* const_type = T.Constant(value); |
| 1255 Type* class_type = T.Class(map); | 1248 AstType* class_type = T.Class(map); |
| 1256 CHECK(!class_type->Maybe(const_type)); | 1249 CHECK(!class_type->Maybe(const_type)); |
| 1257 } | 1250 } |
| 1258 } | 1251 } |
| 1259 */ | 1252 */ |
| 1260 | 1253 |
| 1261 // Basic types | 1254 // Basic types |
| 1262 CheckDisjoint(T.Boolean, T.Null); | 1255 CheckDisjoint(T.Boolean, T.Null); |
| 1263 CheckDisjoint(T.Undefined, T.Null); | 1256 CheckDisjoint(T.Undefined, T.Null); |
| 1264 CheckDisjoint(T.Boolean, T.Undefined); | 1257 CheckDisjoint(T.Boolean, T.Undefined); |
| 1265 CheckOverlap(T.SignedSmall, T.Number); | 1258 CheckOverlap(T.SignedSmall, T.Number); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1300 CheckOverlap(T.ObjectConstant2, T.ArrayClass); | 1293 CheckOverlap(T.ObjectConstant2, T.ArrayClass); |
| 1301 CheckOverlap(T.ArrayConstant, T.ObjectClass); | 1294 CheckOverlap(T.ArrayConstant, T.ObjectClass); |
| 1302 CheckOverlap(T.NumberArray, T.Receiver); | 1295 CheckOverlap(T.NumberArray, T.Receiver); |
| 1303 CheckDisjoint(T.NumberArray, T.AnyArray); | 1296 CheckDisjoint(T.NumberArray, T.AnyArray); |
| 1304 CheckDisjoint(T.NumberArray, T.StringArray); | 1297 CheckDisjoint(T.NumberArray, T.StringArray); |
| 1305 CheckOverlap(T.MethodFunction, T.Object); | 1298 CheckOverlap(T.MethodFunction, T.Object); |
| 1306 CheckDisjoint(T.SignedFunction1, T.NumberFunction1); | 1299 CheckDisjoint(T.SignedFunction1, T.NumberFunction1); |
| 1307 CheckDisjoint(T.SignedFunction1, T.NumberFunction2); | 1300 CheckDisjoint(T.SignedFunction1, T.NumberFunction2); |
| 1308 CheckDisjoint(T.NumberFunction1, T.NumberFunction2); | 1301 CheckDisjoint(T.NumberFunction1, T.NumberFunction2); |
| 1309 CheckDisjoint(T.SignedFunction1, T.MethodFunction); | 1302 CheckDisjoint(T.SignedFunction1, T.MethodFunction); |
| 1310 CheckOverlap(T.ObjectConstant1, T.ObjectClass); // !!! | 1303 CheckOverlap(T.ObjectConstant1, T.ObjectClass); // !!! |
| 1311 CheckOverlap(T.ObjectConstant2, T.ObjectClass); // !!! | 1304 CheckOverlap(T.ObjectConstant2, T.ObjectClass); // !!! |
| 1312 CheckOverlap(T.NumberClass, T.Intersect(T.Number, T.Tagged)); // !!! | 1305 CheckOverlap(T.NumberClass, T.Intersect(T.Number, T.Tagged)); // !!! |
| 1313 } | 1306 } |
| 1314 | 1307 |
| 1315 void Union1() { | 1308 void Union1() { |
| 1316 // Identity: Union(T, None) = T | 1309 // Identity: Union(T, None) = T |
| 1317 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 1310 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 1318 Type* type = *it; | 1311 AstType* type = *it; |
| 1319 Type* union_type = T.Union(type, T.None); | 1312 AstType* union_type = T.Union(type, T.None); |
| 1320 CheckEqual(union_type, type); | 1313 CheckEqual(union_type, type); |
| 1321 } | 1314 } |
| 1322 | 1315 |
| 1323 // Domination: Union(T, Any) = Any | 1316 // Domination: Union(T, Any) = Any |
| 1324 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 1317 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 1325 Type* type = *it; | 1318 AstType* type = *it; |
| 1326 Type* union_type = T.Union(type, T.Any); | 1319 AstType* union_type = T.Union(type, T.Any); |
| 1327 CheckEqual(union_type, T.Any); | 1320 CheckEqual(union_type, T.Any); |
| 1328 } | 1321 } |
| 1329 | 1322 |
| 1330 // Idempotence: Union(T, T) = T | 1323 // Idempotence: Union(T, T) = T |
| 1331 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 1324 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 1332 Type* type = *it; | 1325 AstType* type = *it; |
| 1333 Type* union_type = T.Union(type, type); | 1326 AstType* union_type = T.Union(type, type); |
| 1334 CheckEqual(union_type, type); | 1327 CheckEqual(union_type, type); |
| 1335 } | 1328 } |
| 1336 | 1329 |
| 1337 // Commutativity: Union(T1, T2) = Union(T2, T1) | 1330 // Commutativity: Union(T1, T2) = Union(T2, T1) |
| 1338 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 1331 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1339 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 1332 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1340 Type* type1 = *it1; | 1333 AstType* type1 = *it1; |
| 1341 Type* type2 = *it2; | 1334 AstType* type2 = *it2; |
| 1342 Type* union12 = T.Union(type1, type2); | 1335 AstType* union12 = T.Union(type1, type2); |
| 1343 Type* union21 = T.Union(type2, type1); | 1336 AstType* union21 = T.Union(type2, type1); |
| 1344 CheckEqual(union12, union21); | 1337 CheckEqual(union12, union21); |
| 1345 } | 1338 } |
| 1346 } | 1339 } |
| 1347 | 1340 |
| 1348 // Associativity: Union(T1, Union(T2, T3)) = Union(Union(T1, T2), T3) | 1341 // Associativity: Union(T1, Union(T2, T3)) = Union(Union(T1, T2), T3) |
| 1349 // This does NOT hold! For example: | 1342 // This does NOT hold! For example: |
| 1350 // (Unsigned32 \/ Range(0,5)) \/ Range(-5,0) = Unsigned32 \/ Range(-5,0) | 1343 // (Unsigned32 \/ Range(0,5)) \/ Range(-5,0) = Unsigned32 \/ Range(-5,0) |
| 1351 // Unsigned32 \/ (Range(0,5) \/ Range(-5,0)) = Unsigned32 \/ Range(-5,5) | 1344 // Unsigned32 \/ (Range(0,5) \/ Range(-5,0)) = Unsigned32 \/ Range(-5,5) |
| 1352 /* | 1345 /* |
| 1353 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 1346 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1354 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 1347 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1355 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { | 1348 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { |
| 1356 Type* type1 = *it1; | 1349 AstType* type1 = *it1; |
| 1357 Type* type2 = *it2; | 1350 AstType* type2 = *it2; |
| 1358 Type* type3 = *it3; | 1351 AstType* type3 = *it3; |
| 1359 Type* union12 = T.Union(type1, type2); | 1352 AstType* union12 = T.Union(type1, type2); |
| 1360 Type* union23 = T.Union(type2, type3); | 1353 AstType* union23 = T.Union(type2, type3); |
| 1361 Type* union1_23 = T.Union(type1, union23); | 1354 AstType* union1_23 = T.Union(type1, union23); |
| 1362 Type* union12_3 = T.Union(union12, type3); | 1355 AstType* union12_3 = T.Union(union12, type3); |
| 1363 CheckEqual(union1_23, union12_3); | 1356 CheckEqual(union1_23, union12_3); |
| 1364 } | 1357 } |
| 1365 } | 1358 } |
| 1366 } | 1359 } |
| 1367 */ | 1360 */ |
| 1368 | 1361 |
| 1369 // Meet: T1->Is(Union(T1, T2)) and T2->Is(Union(T1, T2)) | 1362 // Meet: T1->Is(Union(T1, T2)) and T2->Is(Union(T1, T2)) |
| 1370 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 1363 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1371 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 1364 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1372 Type* type1 = *it1; | 1365 AstType* type1 = *it1; |
| 1373 Type* type2 = *it2; | 1366 AstType* type2 = *it2; |
| 1374 Type* union12 = T.Union(type1, type2); | 1367 AstType* union12 = T.Union(type1, type2); |
| 1375 CHECK(type1->Is(union12)); | 1368 CHECK(type1->Is(union12)); |
| 1376 CHECK(type2->Is(union12)); | 1369 CHECK(type2->Is(union12)); |
| 1377 } | 1370 } |
| 1378 } | 1371 } |
| 1379 | 1372 |
| 1380 // Upper Boundedness: T1->Is(T2) implies Union(T1, T2) = T2 | 1373 // Upper Boundedness: T1->Is(T2) implies Union(T1, T2) = T2 |
| 1381 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 1374 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1382 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 1375 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1383 Type* type1 = *it1; | 1376 AstType* type1 = *it1; |
| 1384 Type* type2 = *it2; | 1377 AstType* type2 = *it2; |
| 1385 Type* union12 = T.Union(type1, type2); | 1378 AstType* union12 = T.Union(type1, type2); |
| 1386 if (type1->Is(type2)) CheckEqual(union12, type2); | 1379 if (type1->Is(type2)) CheckEqual(union12, type2); |
| 1387 } | 1380 } |
| 1388 } | 1381 } |
| 1389 | 1382 |
| 1390 // Monotonicity: T1->Is(T2) implies Union(T1, T3)->Is(Union(T2, T3)) | 1383 // Monotonicity: T1->Is(T2) implies Union(T1, T3)->Is(Union(T2, T3)) |
| 1391 // This does NOT hold. For example: | 1384 // This does NOT hold. For example: |
| 1392 // Range(-5,-1) <= Signed32 | 1385 // Range(-5,-1) <= Signed32 |
| 1393 // Range(-5,-1) \/ Range(1,5) = Range(-5,5) </= Signed32 \/ Range(1,5) | 1386 // Range(-5,-1) \/ Range(1,5) = Range(-5,5) </= Signed32 \/ Range(1,5) |
| 1394 /* | 1387 /* |
| 1395 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 1388 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1396 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 1389 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1397 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { | 1390 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { |
| 1398 Type* type1 = *it1; | 1391 AstType* type1 = *it1; |
| 1399 Type* type2 = *it2; | 1392 AstType* type2 = *it2; |
| 1400 Type* type3 = *it3; | 1393 AstType* type3 = *it3; |
| 1401 Type* union13 = T.Union(type1, type3); | 1394 AstType* union13 = T.Union(type1, type3); |
| 1402 Type* union23 = T.Union(type2, type3); | 1395 AstType* union23 = T.Union(type2, type3); |
| 1403 CHECK(!type1->Is(type2) || union13->Is(union23)); | 1396 CHECK(!type1->Is(type2) || union13->Is(union23)); |
| 1404 } | 1397 } |
| 1405 } | 1398 } |
| 1406 } | 1399 } |
| 1407 */ | 1400 */ |
| 1408 } | 1401 } |
| 1409 | 1402 |
| 1410 void Union2() { | 1403 void Union2() { |
| 1411 // Monotonicity: T1->Is(T3) and T2->Is(T3) implies Union(T1, T2)->Is(T3) | 1404 // Monotonicity: T1->Is(T3) and T2->Is(T3) implies Union(T1, T2)->Is(T3) |
| 1412 // This does NOT hold. For example: | 1405 // This does NOT hold. For example: |
| 1413 // Range(-2^33, -2^33) <= OtherNumber | 1406 // Range(-2^33, -2^33) <= OtherNumber |
| 1414 // Range(2^33, 2^33) <= OtherNumber | 1407 // Range(2^33, 2^33) <= OtherNumber |
| 1415 // Range(-2^33, 2^33) </= OtherNumber | 1408 // Range(-2^33, 2^33) </= OtherNumber |
| 1416 /* | 1409 /* |
| 1417 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 1410 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1418 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 1411 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1419 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { | 1412 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { |
| 1420 Type* type1 = *it1; | 1413 AstType* type1 = *it1; |
| 1421 Type* type2 = *it2; | 1414 AstType* type2 = *it2; |
| 1422 Type* type3 = *it3; | 1415 AstType* type3 = *it3; |
| 1423 Type* union12 = T.Union(type1, type2); | 1416 AstType* union12 = T.Union(type1, type2); |
| 1424 CHECK(!(type1->Is(type3) && type2->Is(type3)) || union12->Is(type3)); | 1417 CHECK(!(type1->Is(type3) && type2->Is(type3)) || union12->Is(type3)); |
| 1425 } | 1418 } |
| 1426 } | 1419 } |
| 1427 } | 1420 } |
| 1428 */ | 1421 */ |
| 1429 } | 1422 } |
| 1430 | 1423 |
| 1431 void Union3() { | 1424 void Union3() { |
| 1432 // Monotonicity: T1->Is(T2) or T1->Is(T3) implies T1->Is(Union(T2, T3)) | 1425 // Monotonicity: T1->Is(T2) or T1->Is(T3) implies T1->Is(Union(T2, T3)) |
| 1433 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 1426 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1434 HandleScope scope(isolate); | 1427 HandleScope scope(isolate); |
| 1435 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 1428 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1436 for (TypeIterator it3 = it2; it3 != T.types.end(); ++it3) { | 1429 for (TypeIterator it3 = it2; it3 != T.types.end(); ++it3) { |
| 1437 Type* type1 = *it1; | 1430 AstType* type1 = *it1; |
| 1438 Type* type2 = *it2; | 1431 AstType* type2 = *it2; |
| 1439 Type* type3 = *it3; | 1432 AstType* type3 = *it3; |
| 1440 Type* union23 = T.Union(type2, type3); | 1433 AstType* union23 = T.Union(type2, type3); |
| 1441 CHECK(!(type1->Is(type2) || type1->Is(type3)) || type1->Is(union23)); | 1434 CHECK(!(type1->Is(type2) || type1->Is(type3)) || type1->Is(union23)); |
| 1442 } | 1435 } |
| 1443 } | 1436 } |
| 1444 } | 1437 } |
| 1445 } | 1438 } |
| 1446 | 1439 |
| 1447 void Union4() { | 1440 void Union4() { |
| 1448 // Class-class | 1441 // Class-class |
| 1449 CheckSub(T.Union(T.ObjectClass, T.ArrayClass), T.Object); | 1442 CheckSub(T.Union(T.ObjectClass, T.ArrayClass), T.Object); |
| 1450 CheckOverlap(T.Union(T.ObjectClass, T.ArrayClass), T.OtherObject); | 1443 CheckOverlap(T.Union(T.ObjectClass, T.ArrayClass), T.OtherObject); |
| 1451 CheckOverlap(T.Union(T.ObjectClass, T.ArrayClass), T.Receiver); | 1444 CheckOverlap(T.Union(T.ObjectClass, T.ArrayClass), T.Receiver); |
| 1452 CheckDisjoint(T.Union(T.ObjectClass, T.ArrayClass), T.Number); | 1445 CheckDisjoint(T.Union(T.ObjectClass, T.ArrayClass), T.Number); |
| 1453 | 1446 |
| 1454 // Constant-constant | 1447 // Constant-constant |
| 1455 CheckSub(T.Union(T.ObjectConstant1, T.ObjectConstant2), T.Object); | 1448 CheckSub(T.Union(T.ObjectConstant1, T.ObjectConstant2), T.Object); |
| 1456 CheckOverlap(T.Union(T.ObjectConstant1, T.ArrayConstant), T.OtherObject); | 1449 CheckOverlap(T.Union(T.ObjectConstant1, T.ArrayConstant), T.OtherObject); |
| 1457 CheckUnordered( | 1450 CheckUnordered(T.Union(T.ObjectConstant1, T.ObjectConstant2), |
| 1458 T.Union(T.ObjectConstant1, T.ObjectConstant2), T.ObjectClass); | 1451 T.ObjectClass); |
| 1459 CheckOverlap(T.Union(T.ObjectConstant1, T.ArrayConstant), T.OtherObject); | 1452 CheckOverlap(T.Union(T.ObjectConstant1, T.ArrayConstant), T.OtherObject); |
| 1460 CheckDisjoint( | 1453 CheckDisjoint(T.Union(T.ObjectConstant1, T.ArrayConstant), T.Number); |
| 1461 T.Union(T.ObjectConstant1, T.ArrayConstant), T.Number); | 1454 CheckOverlap(T.Union(T.ObjectConstant1, T.ArrayConstant), |
| 1462 CheckOverlap( | 1455 T.ObjectClass); // !!! |
| 1463 T.Union(T.ObjectConstant1, T.ArrayConstant), T.ObjectClass); // !!! | |
| 1464 | 1456 |
| 1465 // Bitset-array | 1457 // Bitset-array |
| 1466 CHECK(this->IsBitset(T.Union(T.AnyArray, T.Receiver))); | 1458 CHECK(this->IsBitset(T.Union(T.AnyArray, T.Receiver))); |
| 1467 CHECK(this->IsUnion(T.Union(T.NumberArray, T.Number))); | 1459 CHECK(this->IsUnion(T.Union(T.NumberArray, T.Number))); |
| 1468 | 1460 |
| 1469 CheckEqual(T.Union(T.AnyArray, T.Receiver), T.Receiver); | 1461 CheckEqual(T.Union(T.AnyArray, T.Receiver), T.Receiver); |
| 1470 CheckEqual(T.Union(T.AnyArray, T.OtherObject), T.OtherObject); | 1462 CheckEqual(T.Union(T.AnyArray, T.OtherObject), T.OtherObject); |
| 1471 CheckUnordered(T.Union(T.AnyArray, T.String), T.Receiver); | 1463 CheckUnordered(T.Union(T.AnyArray, T.String), T.Receiver); |
| 1472 CheckOverlap(T.Union(T.NumberArray, T.String), T.Object); | 1464 CheckOverlap(T.Union(T.NumberArray, T.String), T.Object); |
| 1473 CheckDisjoint(T.Union(T.NumberArray, T.String), T.Number); | 1465 CheckDisjoint(T.Union(T.NumberArray, T.String), T.Number); |
| 1474 | 1466 |
| 1475 // Bitset-function | 1467 // Bitset-function |
| 1476 CHECK(this->IsBitset(T.Union(T.MethodFunction, T.Object))); | 1468 CHECK(this->IsBitset(T.Union(T.MethodFunction, T.Object))); |
| 1477 CHECK(this->IsUnion(T.Union(T.NumberFunction1, T.Number))); | 1469 CHECK(this->IsUnion(T.Union(T.NumberFunction1, T.Number))); |
| 1478 | 1470 |
| 1479 CheckEqual(T.Union(T.MethodFunction, T.Object), T.Object); | 1471 CheckEqual(T.Union(T.MethodFunction, T.Object), T.Object); |
| 1480 CheckUnordered(T.Union(T.NumberFunction1, T.String), T.Object); | 1472 CheckUnordered(T.Union(T.NumberFunction1, T.String), T.Object); |
| 1481 CheckOverlap(T.Union(T.NumberFunction2, T.String), T.Object); | 1473 CheckOverlap(T.Union(T.NumberFunction2, T.String), T.Object); |
| 1482 CheckDisjoint(T.Union(T.NumberFunction1, T.String), T.Number); | 1474 CheckDisjoint(T.Union(T.NumberFunction1, T.String), T.Number); |
| 1483 | 1475 |
| 1484 // Bitset-class | 1476 // Bitset-class |
| 1485 CheckSub(T.Union(T.ObjectClass, T.SignedSmall), | 1477 CheckSub(T.Union(T.ObjectClass, T.SignedSmall), |
| 1486 T.Union(T.Object, T.Number)); | 1478 T.Union(T.Object, T.Number)); |
| 1487 CheckSub(T.Union(T.ObjectClass, T.OtherObject), T.Object); | 1479 CheckSub(T.Union(T.ObjectClass, T.OtherObject), T.Object); |
| 1488 CheckUnordered(T.Union(T.ObjectClass, T.String), T.OtherObject); | 1480 CheckUnordered(T.Union(T.ObjectClass, T.String), T.OtherObject); |
| 1489 CheckOverlap(T.Union(T.ObjectClass, T.String), T.Object); | 1481 CheckOverlap(T.Union(T.ObjectClass, T.String), T.Object); |
| 1490 CheckDisjoint(T.Union(T.ObjectClass, T.String), T.Number); | 1482 CheckDisjoint(T.Union(T.ObjectClass, T.String), T.Number); |
| 1491 | 1483 |
| 1492 // Bitset-constant | 1484 // Bitset-constant |
| 1493 CheckSub( | 1485 CheckSub(T.Union(T.ObjectConstant1, T.Signed32), |
| 1494 T.Union(T.ObjectConstant1, T.Signed32), T.Union(T.Object, T.Number)); | 1486 T.Union(T.Object, T.Number)); |
| 1495 CheckSub(T.Union(T.ObjectConstant1, T.OtherObject), T.Object); | 1487 CheckSub(T.Union(T.ObjectConstant1, T.OtherObject), T.Object); |
| 1496 CheckUnordered(T.Union(T.ObjectConstant1, T.String), T.OtherObject); | 1488 CheckUnordered(T.Union(T.ObjectConstant1, T.String), T.OtherObject); |
| 1497 CheckOverlap(T.Union(T.ObjectConstant1, T.String), T.Object); | 1489 CheckOverlap(T.Union(T.ObjectConstant1, T.String), T.Object); |
| 1498 CheckDisjoint(T.Union(T.ObjectConstant1, T.String), T.Number); | 1490 CheckDisjoint(T.Union(T.ObjectConstant1, T.String), T.Number); |
| 1499 | 1491 |
| 1500 // Class-constant | 1492 // Class-constant |
| 1501 CheckSub(T.Union(T.ObjectConstant1, T.ArrayClass), T.Object); | 1493 CheckSub(T.Union(T.ObjectConstant1, T.ArrayClass), T.Object); |
| 1502 CheckUnordered(T.ObjectClass, T.Union(T.ObjectConstant1, T.ArrayClass)); | 1494 CheckUnordered(T.ObjectClass, T.Union(T.ObjectConstant1, T.ArrayClass)); |
| 1503 CheckSub(T.Union(T.ObjectConstant1, T.ArrayClass), | 1495 CheckSub(T.Union(T.ObjectConstant1, T.ArrayClass), |
| 1504 T.Union(T.Receiver, T.Object)); | 1496 T.Union(T.Receiver, T.Object)); |
| 1505 CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayClass), T.ArrayConstant); | 1497 CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayClass), T.ArrayConstant); |
| 1506 CheckOverlap(T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectConstant2); | 1498 CheckOverlap(T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectConstant2); |
| 1507 CheckOverlap( | 1499 CheckOverlap(T.Union(T.ObjectConstant1, T.ArrayClass), |
| 1508 T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectClass); // !!! | 1500 T.ObjectClass); // !!! |
| 1509 | 1501 |
| 1510 // Bitset-union | 1502 // Bitset-union |
| 1511 CheckSub( | 1503 CheckSub(T.NaN, |
| 1512 T.NaN, | 1504 T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number)); |
| 1513 T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number)); | 1505 CheckSub(T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Signed32), |
| 1514 CheckSub( | 1506 T.Union(T.ObjectConstant1, T.Union(T.Number, T.ArrayClass))); |
| 1515 T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Signed32), | |
| 1516 T.Union(T.ObjectConstant1, T.Union(T.Number, T.ArrayClass))); | |
| 1517 | 1507 |
| 1518 // Class-union | 1508 // Class-union |
| 1519 CheckSub( | 1509 CheckSub(T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)), |
| 1520 T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)), | 1510 T.Object); |
| 1521 T.Object); | 1511 CheckEqual(T.Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass), |
| 1522 CheckEqual( | 1512 T.Union(T.ArrayClass, T.ObjectConstant2)); |
| 1523 T.Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass), | |
| 1524 T.Union(T.ArrayClass, T.ObjectConstant2)); | |
| 1525 | 1513 |
| 1526 // Constant-union | 1514 // Constant-union |
| 1515 CheckEqual(T.Union(T.ObjectConstant1, |
| 1516 T.Union(T.ObjectConstant1, T.ObjectConstant2)), |
| 1517 T.Union(T.ObjectConstant2, T.ObjectConstant1)); |
| 1527 CheckEqual( | 1518 CheckEqual( |
| 1528 T.Union( | 1519 T.Union(T.Union(T.ArrayConstant, T.ObjectConstant2), T.ObjectConstant1), |
| 1529 T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)), | 1520 T.Union(T.ObjectConstant2, |
| 1530 T.Union(T.ObjectConstant2, T.ObjectConstant1)); | 1521 T.Union(T.ArrayConstant, T.ObjectConstant1))); |
| 1531 CheckEqual( | |
| 1532 T.Union( | |
| 1533 T.Union(T.ArrayConstant, T.ObjectConstant2), T.ObjectConstant1), | |
| 1534 T.Union( | |
| 1535 T.ObjectConstant2, T.Union(T.ArrayConstant, T.ObjectConstant1))); | |
| 1536 | 1522 |
| 1537 // Array-union | 1523 // Array-union |
| 1538 CheckEqual( | 1524 CheckEqual(T.Union(T.AnyArray, T.Union(T.NumberArray, T.AnyArray)), |
| 1539 T.Union(T.AnyArray, T.Union(T.NumberArray, T.AnyArray)), | 1525 T.Union(T.AnyArray, T.NumberArray)); |
| 1540 T.Union(T.AnyArray, T.NumberArray)); | |
| 1541 CheckSub(T.Union(T.AnyArray, T.NumberArray), T.OtherObject); | 1526 CheckSub(T.Union(T.AnyArray, T.NumberArray), T.OtherObject); |
| 1542 | 1527 |
| 1543 // Function-union | 1528 // Function-union |
| 1544 CheckEqual( | 1529 CheckEqual(T.Union(T.NumberFunction1, T.NumberFunction2), |
| 1545 T.Union(T.NumberFunction1, T.NumberFunction2), | 1530 T.Union(T.NumberFunction2, T.NumberFunction1)); |
| 1546 T.Union(T.NumberFunction2, T.NumberFunction1)); | |
| 1547 CheckSub(T.Union(T.SignedFunction1, T.MethodFunction), T.Object); | 1531 CheckSub(T.Union(T.SignedFunction1, T.MethodFunction), T.Object); |
| 1548 | 1532 |
| 1549 // Union-union | 1533 // Union-union |
| 1550 CheckEqual( | 1534 CheckEqual(T.Union(T.Union(T.ObjectConstant2, T.ObjectConstant1), |
| 1551 T.Union( | 1535 T.Union(T.ObjectConstant1, T.ObjectConstant2)), |
| 1552 T.Union(T.ObjectConstant2, T.ObjectConstant1), | 1536 T.Union(T.ObjectConstant2, T.ObjectConstant1)); |
| 1553 T.Union(T.ObjectConstant1, T.ObjectConstant2)), | |
| 1554 T.Union(T.ObjectConstant2, T.ObjectConstant1)); | |
| 1555 CheckEqual(T.Union(T.Union(T.Number, T.ArrayClass), | 1537 CheckEqual(T.Union(T.Union(T.Number, T.ArrayClass), |
| 1556 T.Union(T.SignedSmall, T.Receiver)), | 1538 T.Union(T.SignedSmall, T.Receiver)), |
| 1557 T.Union(T.Number, T.Receiver)); | 1539 T.Union(T.Number, T.Receiver)); |
| 1558 } | 1540 } |
| 1559 | 1541 |
| 1560 void Intersect() { | 1542 void Intersect() { |
| 1561 // Identity: Intersect(T, Any) = T | 1543 // Identity: Intersect(T, Any) = T |
| 1562 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 1544 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 1563 Type* type = *it; | 1545 AstType* type = *it; |
| 1564 Type* intersect_type = T.Intersect(type, T.Any); | 1546 AstType* intersect_type = T.Intersect(type, T.Any); |
| 1565 CheckEqual(intersect_type, type); | 1547 CheckEqual(intersect_type, type); |
| 1566 } | 1548 } |
| 1567 | 1549 |
| 1568 // Domination: Intersect(T, None) = None | 1550 // Domination: Intersect(T, None) = None |
| 1569 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 1551 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 1570 Type* type = *it; | 1552 AstType* type = *it; |
| 1571 Type* intersect_type = T.Intersect(type, T.None); | 1553 AstType* intersect_type = T.Intersect(type, T.None); |
| 1572 CheckEqual(intersect_type, T.None); | 1554 CheckEqual(intersect_type, T.None); |
| 1573 } | 1555 } |
| 1574 | 1556 |
| 1575 // Idempotence: Intersect(T, T) = T | 1557 // Idempotence: Intersect(T, T) = T |
| 1576 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 1558 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 1577 Type* type = *it; | 1559 AstType* type = *it; |
| 1578 Type* intersect_type = T.Intersect(type, type); | 1560 AstType* intersect_type = T.Intersect(type, type); |
| 1579 CheckEqual(intersect_type, type); | 1561 CheckEqual(intersect_type, type); |
| 1580 } | 1562 } |
| 1581 | 1563 |
| 1582 // Commutativity: Intersect(T1, T2) = Intersect(T2, T1) | 1564 // Commutativity: Intersect(T1, T2) = Intersect(T2, T1) |
| 1583 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 1565 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1584 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 1566 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1585 Type* type1 = *it1; | 1567 AstType* type1 = *it1; |
| 1586 Type* type2 = *it2; | 1568 AstType* type2 = *it2; |
| 1587 Type* intersect12 = T.Intersect(type1, type2); | 1569 AstType* intersect12 = T.Intersect(type1, type2); |
| 1588 Type* intersect21 = T.Intersect(type2, type1); | 1570 AstType* intersect21 = T.Intersect(type2, type1); |
| 1589 CheckEqual(intersect12, intersect21); | 1571 CheckEqual(intersect12, intersect21); |
| 1590 } | 1572 } |
| 1591 } | 1573 } |
| 1592 | 1574 |
| 1593 // Associativity: | 1575 // Associativity: |
| 1594 // Intersect(T1, Intersect(T2, T3)) = Intersect(Intersect(T1, T2), T3) | 1576 // Intersect(T1, Intersect(T2, T3)) = Intersect(Intersect(T1, T2), T3) |
| 1595 // This does NOT hold. For example: | 1577 // This does NOT hold. For example: |
| 1596 // (Class(..stringy1..) /\ Class(..stringy2..)) /\ Constant(..string..) = | 1578 // (Class(..stringy1..) /\ Class(..stringy2..)) /\ Constant(..string..) = |
| 1597 // None | 1579 // None |
| 1598 // Class(..stringy1..) /\ (Class(..stringy2..) /\ Constant(..string..)) = | 1580 // Class(..stringy1..) /\ (Class(..stringy2..) /\ Constant(..string..)) = |
| 1599 // Constant(..string..) | 1581 // Constant(..string..) |
| 1600 /* | 1582 /* |
| 1601 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 1583 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1602 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 1584 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1603 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { | 1585 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { |
| 1604 Type* type1 = *it1; | 1586 AstType* type1 = *it1; |
| 1605 Type* type2 = *it2; | 1587 AstType* type2 = *it2; |
| 1606 Type* type3 = *it3; | 1588 AstType* type3 = *it3; |
| 1607 Type* intersect12 = T.Intersect(type1, type2); | 1589 AstType* intersect12 = T.Intersect(type1, type2); |
| 1608 Type* intersect23 = T.Intersect(type2, type3); | 1590 AstType* intersect23 = T.Intersect(type2, type3); |
| 1609 Type* intersect1_23 = T.Intersect(type1, intersect23); | 1591 AstType* intersect1_23 = T.Intersect(type1, intersect23); |
| 1610 Type* intersect12_3 = T.Intersect(intersect12, type3); | 1592 AstType* intersect12_3 = T.Intersect(intersect12, type3); |
| 1611 CheckEqual(intersect1_23, intersect12_3); | 1593 CheckEqual(intersect1_23, intersect12_3); |
| 1612 } | 1594 } |
| 1613 } | 1595 } |
| 1614 } | 1596 } |
| 1615 */ | 1597 */ |
| 1616 | 1598 |
| 1617 // Join: Intersect(T1, T2)->Is(T1) and Intersect(T1, T2)->Is(T2) | 1599 // Join: Intersect(T1, T2)->Is(T1) and Intersect(T1, T2)->Is(T2) |
| 1618 // This does NOT hold. For example: | 1600 // This does NOT hold. For example: |
| 1619 // Class(..stringy..) /\ Constant(..string..) = Constant(..string..) | 1601 // Class(..stringy..) /\ Constant(..string..) = Constant(..string..) |
| 1620 // Currently, not even the disjunction holds: | 1602 // Currently, not even the disjunction holds: |
| 1621 // Class(Internal/TaggedPtr) /\ (Any/Untagged \/ Context(..)) = | 1603 // Class(Internal/TaggedPtr) /\ (Any/Untagged \/ Context(..)) = |
| 1622 // Class(Internal/TaggedPtr) \/ Context(..) | 1604 // Class(Internal/TaggedPtr) \/ Context(..) |
| 1623 /* | 1605 /* |
| 1624 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 1606 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1625 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 1607 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1626 Type* type1 = *it1; | 1608 AstType* type1 = *it1; |
| 1627 Type* type2 = *it2; | 1609 AstType* type2 = *it2; |
| 1628 Type* intersect12 = T.Intersect(type1, type2); | 1610 AstType* intersect12 = T.Intersect(type1, type2); |
| 1629 CHECK(intersect12->Is(type1)); | 1611 CHECK(intersect12->Is(type1)); |
| 1630 CHECK(intersect12->Is(type2)); | 1612 CHECK(intersect12->Is(type2)); |
| 1631 } | 1613 } |
| 1632 } | 1614 } |
| 1633 */ | 1615 */ |
| 1634 | 1616 |
| 1635 // Lower Boundedness: T1->Is(T2) implies Intersect(T1, T2) = T1 | 1617 // Lower Boundedness: T1->Is(T2) implies Intersect(T1, T2) = T1 |
| 1636 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 1618 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1637 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 1619 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1638 Type* type1 = *it1; | 1620 AstType* type1 = *it1; |
| 1639 Type* type2 = *it2; | 1621 AstType* type2 = *it2; |
| 1640 Type* intersect12 = T.Intersect(type1, type2); | 1622 AstType* intersect12 = T.Intersect(type1, type2); |
| 1641 if (type1->Is(type2)) CheckEqual(intersect12, type1); | 1623 if (type1->Is(type2)) CheckEqual(intersect12, type1); |
| 1642 } | 1624 } |
| 1643 } | 1625 } |
| 1644 | 1626 |
| 1645 // Monotonicity: T1->Is(T2) implies Intersect(T1, T3)->Is(Intersect(T2, T3)) | 1627 // Monotonicity: T1->Is(T2) implies Intersect(T1, T3)->Is(Intersect(T2, T3)) |
| 1646 // This does NOT hold. For example: | 1628 // This does NOT hold. For example: |
| 1647 // Class(OtherObject/TaggedPtr) <= Any/TaggedPtr | 1629 // Class(OtherObject/TaggedPtr) <= Any/TaggedPtr |
| 1648 // Class(OtherObject/TaggedPtr) /\ Any/UntaggedInt1 = Class(..) | 1630 // Class(OtherObject/TaggedPtr) /\ Any/UntaggedInt1 = Class(..) |
| 1649 // Any/TaggedPtr /\ Any/UntaggedInt1 = None | 1631 // Any/TaggedPtr /\ Any/UntaggedInt1 = None |
| 1650 /* | 1632 /* |
| 1651 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 1633 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1652 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 1634 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1653 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { | 1635 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { |
| 1654 Type* type1 = *it1; | 1636 AstType* type1 = *it1; |
| 1655 Type* type2 = *it2; | 1637 AstType* type2 = *it2; |
| 1656 Type* type3 = *it3; | 1638 AstType* type3 = *it3; |
| 1657 Type* intersect13 = T.Intersect(type1, type3); | 1639 AstType* intersect13 = T.Intersect(type1, type3); |
| 1658 Type* intersect23 = T.Intersect(type2, type3); | 1640 AstType* intersect23 = T.Intersect(type2, type3); |
| 1659 CHECK(!type1->Is(type2) || intersect13->Is(intersect23)); | 1641 CHECK(!type1->Is(type2) || intersect13->Is(intersect23)); |
| 1660 } | 1642 } |
| 1661 } | 1643 } |
| 1662 } | 1644 } |
| 1663 */ | 1645 */ |
| 1664 | 1646 |
| 1665 // Monotonicity: T1->Is(T3) or T2->Is(T3) implies Intersect(T1, T2)->Is(T3) | 1647 // Monotonicity: T1->Is(T3) or T2->Is(T3) implies Intersect(T1, T2)->Is(T3) |
| 1666 // This does NOT hold. For example: | 1648 // This does NOT hold. For example: |
| 1667 // Class(..stringy..) <= Class(..stringy..) | 1649 // Class(..stringy..) <= Class(..stringy..) |
| 1668 // Class(..stringy..) /\ Constant(..string..) = Constant(..string..) | 1650 // Class(..stringy..) /\ Constant(..string..) = Constant(..string..) |
| 1669 // Constant(..string..) </= Class(..stringy..) | 1651 // Constant(..string..) </= Class(..stringy..) |
| 1670 /* | 1652 /* |
| 1671 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 1653 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1672 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 1654 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1673 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { | 1655 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { |
| 1674 Type* type1 = *it1; | 1656 AstType* type1 = *it1; |
| 1675 Type* type2 = *it2; | 1657 AstType* type2 = *it2; |
| 1676 Type* type3 = *it3; | 1658 AstType* type3 = *it3; |
| 1677 Type* intersect12 = T.Intersect(type1, type2); | 1659 AstType* intersect12 = T.Intersect(type1, type2); |
| 1678 CHECK(!(type1->Is(type3) || type2->Is(type3)) || | 1660 CHECK(!(type1->Is(type3) || type2->Is(type3)) || |
| 1679 intersect12->Is(type3)); | 1661 intersect12->Is(type3)); |
| 1680 } | 1662 } |
| 1681 } | 1663 } |
| 1682 } | 1664 } |
| 1683 */ | 1665 */ |
| 1684 | 1666 |
| 1685 // Monotonicity: T1->Is(T2) and T1->Is(T3) implies T1->Is(Intersect(T2, T3)) | 1667 // Monotonicity: T1->Is(T2) and T1->Is(T3) implies T1->Is(Intersect(T2, T3)) |
| 1686 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 1668 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1687 HandleScope scope(isolate); | 1669 HandleScope scope(isolate); |
| 1688 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 1670 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1689 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { | 1671 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { |
| 1690 Type* type1 = *it1; | 1672 AstType* type1 = *it1; |
| 1691 Type* type2 = *it2; | 1673 AstType* type2 = *it2; |
| 1692 Type* type3 = *it3; | 1674 AstType* type3 = *it3; |
| 1693 Type* intersect23 = T.Intersect(type2, type3); | 1675 AstType* intersect23 = T.Intersect(type2, type3); |
| 1694 CHECK(!(type1->Is(type2) && type1->Is(type3)) || | 1676 CHECK(!(type1->Is(type2) && type1->Is(type3)) || |
| 1695 type1->Is(intersect23)); | 1677 type1->Is(intersect23)); |
| 1696 } | 1678 } |
| 1697 } | 1679 } |
| 1698 } | 1680 } |
| 1699 | 1681 |
| 1700 // Bitset-class | 1682 // Bitset-class |
| 1701 CheckEqual(T.Intersect(T.ObjectClass, T.Object), T.ObjectClass); | 1683 CheckEqual(T.Intersect(T.ObjectClass, T.Object), T.ObjectClass); |
| 1702 CheckEqual(T.Semantic(T.Intersect(T.ObjectClass, T.Number)), T.None); | 1684 CheckEqual(T.Semantic(T.Intersect(T.ObjectClass, T.Number)), T.None); |
| 1703 | 1685 |
| 1704 // Bitset-array | 1686 // Bitset-array |
| 1705 CheckEqual(T.Intersect(T.NumberArray, T.Object), T.NumberArray); | 1687 CheckEqual(T.Intersect(T.NumberArray, T.Object), T.NumberArray); |
| 1706 CheckEqual(T.Semantic(T.Intersect(T.AnyArray, T.Proxy)), T.None); | 1688 CheckEqual(T.Semantic(T.Intersect(T.AnyArray, T.Proxy)), T.None); |
| 1707 | 1689 |
| 1708 // Bitset-function | 1690 // Bitset-function |
| 1709 CheckEqual(T.Intersect(T.MethodFunction, T.Object), T.MethodFunction); | 1691 CheckEqual(T.Intersect(T.MethodFunction, T.Object), T.MethodFunction); |
| 1710 CheckEqual(T.Semantic(T.Intersect(T.NumberFunction1, T.Proxy)), T.None); | 1692 CheckEqual(T.Semantic(T.Intersect(T.NumberFunction1, T.Proxy)), T.None); |
| 1711 | 1693 |
| 1712 // Bitset-union | 1694 // Bitset-union |
| 1713 CheckEqual( | 1695 CheckEqual(T.Intersect(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)), |
| 1714 T.Intersect(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)), | 1696 T.Union(T.ObjectConstant1, T.ObjectClass)); |
| 1715 T.Union(T.ObjectConstant1, T.ObjectClass)); | |
| 1716 CheckEqual(T.Semantic(T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant1), | 1697 CheckEqual(T.Semantic(T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant1), |
| 1717 T.Number)), | 1698 T.Number)), |
| 1718 T.None); | 1699 T.None); |
| 1719 | 1700 |
| 1720 // Class-constant | 1701 // Class-constant |
| 1721 CHECK(T.Intersect(T.ObjectConstant1, T.ObjectClass)->IsInhabited()); // !!! | 1702 CHECK(T.Intersect(T.ObjectConstant1, T.ObjectClass)->IsInhabited()); // !!! |
| 1722 CHECK(T.Intersect(T.ArrayClass, T.ObjectConstant2)->IsInhabited()); | 1703 CHECK(T.Intersect(T.ArrayClass, T.ObjectConstant2)->IsInhabited()); |
| 1723 | 1704 |
| 1724 // Array-union | 1705 // Array-union |
| 1725 CheckEqual( | 1706 CheckEqual(T.Intersect(T.NumberArray, T.Union(T.NumberArray, T.ArrayClass)), |
| 1726 T.Intersect(T.NumberArray, T.Union(T.NumberArray, T.ArrayClass)), | 1707 T.NumberArray); |
| 1727 T.NumberArray); | 1708 CheckEqual(T.Intersect(T.AnyArray, T.Union(T.Object, T.SmiConstant)), |
| 1728 CheckEqual( | 1709 T.AnyArray); |
| 1729 T.Intersect(T.AnyArray, T.Union(T.Object, T.SmiConstant)), | 1710 CHECK(!T.Intersect(T.Union(T.AnyArray, T.ArrayConstant), T.NumberArray) |
| 1730 T.AnyArray); | 1711 ->IsInhabited()); |
| 1731 CHECK( | |
| 1732 !T.Intersect(T.Union(T.AnyArray, T.ArrayConstant), T.NumberArray) | |
| 1733 ->IsInhabited()); | |
| 1734 | 1712 |
| 1735 // Function-union | 1713 // Function-union |
| 1736 CheckEqual( | 1714 CheckEqual( |
| 1737 T.Intersect(T.MethodFunction, T.Union(T.String, T.MethodFunction)), | 1715 T.Intersect(T.MethodFunction, T.Union(T.String, T.MethodFunction)), |
| 1738 T.MethodFunction); | 1716 T.MethodFunction); |
| 1739 CheckEqual( | 1717 CheckEqual(T.Intersect(T.NumberFunction1, T.Union(T.Object, T.SmiConstant)), |
| 1740 T.Intersect(T.NumberFunction1, T.Union(T.Object, T.SmiConstant)), | 1718 T.NumberFunction1); |
| 1741 T.NumberFunction1); | 1719 CHECK(!T.Intersect(T.Union(T.MethodFunction, T.Name), T.NumberFunction2) |
| 1742 CHECK( | 1720 ->IsInhabited()); |
| 1743 !T.Intersect(T.Union(T.MethodFunction, T.Name), T.NumberFunction2) | |
| 1744 ->IsInhabited()); | |
| 1745 | 1721 |
| 1746 // Class-union | 1722 // Class-union |
| 1747 CheckEqual( | 1723 CheckEqual( |
| 1748 T.Intersect(T.ArrayClass, T.Union(T.ObjectConstant2, T.ArrayClass)), | 1724 T.Intersect(T.ArrayClass, T.Union(T.ObjectConstant2, T.ArrayClass)), |
| 1749 T.ArrayClass); | 1725 T.ArrayClass); |
| 1750 CheckEqual( | 1726 CheckEqual(T.Intersect(T.ArrayClass, T.Union(T.Object, T.SmiConstant)), |
| 1751 T.Intersect(T.ArrayClass, T.Union(T.Object, T.SmiConstant)), | 1727 T.ArrayClass); |
| 1752 T.ArrayClass); | 1728 CHECK(T.Intersect(T.Union(T.ObjectClass, T.ArrayConstant), T.ArrayClass) |
| 1753 CHECK( | 1729 ->IsInhabited()); // !!! |
| 1754 T.Intersect(T.Union(T.ObjectClass, T.ArrayConstant), T.ArrayClass) | |
| 1755 ->IsInhabited()); // !!! | |
| 1756 | 1730 |
| 1757 // Constant-union | 1731 // Constant-union |
| 1758 CheckEqual( | 1732 CheckEqual(T.Intersect(T.ObjectConstant1, |
| 1759 T.Intersect( | 1733 T.Union(T.ObjectConstant1, T.ObjectConstant2)), |
| 1760 T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)), | 1734 T.ObjectConstant1); |
| 1761 T.ObjectConstant1); | 1735 CheckEqual(T.Intersect(T.SmiConstant, T.Union(T.Number, T.ObjectConstant2)), |
| 1762 CheckEqual( | 1736 T.SmiConstant); |
| 1763 T.Intersect(T.SmiConstant, T.Union(T.Number, T.ObjectConstant2)), | |
| 1764 T.SmiConstant); | |
| 1765 CHECK( | 1737 CHECK( |
| 1766 T.Intersect( | 1738 T.Intersect(T.Union(T.ArrayConstant, T.ObjectClass), T.ObjectConstant1) |
| 1767 T.Union(T.ArrayConstant, T.ObjectClass), T.ObjectConstant1) | 1739 ->IsInhabited()); // !!! |
| 1768 ->IsInhabited()); // !!! | |
| 1769 | 1740 |
| 1770 // Union-union | 1741 // Union-union |
| 1771 CheckEqual(T.Intersect(T.Union(T.Number, T.ArrayClass), | 1742 CheckEqual(T.Intersect(T.Union(T.Number, T.ArrayClass), |
| 1772 T.Union(T.SignedSmall, T.Receiver)), | 1743 T.Union(T.SignedSmall, T.Receiver)), |
| 1773 T.Union(T.SignedSmall, T.ArrayClass)); | 1744 T.Union(T.SignedSmall, T.ArrayClass)); |
| 1774 CheckEqual(T.Intersect(T.Union(T.Number, T.ObjectClass), | 1745 CheckEqual(T.Intersect(T.Union(T.Number, T.ObjectClass), |
| 1775 T.Union(T.Signed32, T.OtherObject)), | 1746 T.Union(T.Signed32, T.OtherObject)), |
| 1776 T.Union(T.Signed32, T.ObjectClass)); | 1747 T.Union(T.Signed32, T.ObjectClass)); |
| 1748 CheckEqual(T.Intersect(T.Union(T.ObjectConstant2, T.ObjectConstant1), |
| 1749 T.Union(T.ObjectConstant1, T.ObjectConstant2)), |
| 1750 T.Union(T.ObjectConstant2, T.ObjectConstant1)); |
| 1777 CheckEqual( | 1751 CheckEqual( |
| 1778 T.Intersect( | 1752 T.Intersect(T.Union(T.ArrayClass, |
| 1779 T.Union(T.ObjectConstant2, T.ObjectConstant1), | 1753 T.Union(T.ObjectConstant2, T.ObjectConstant1)), |
| 1780 T.Union(T.ObjectConstant1, T.ObjectConstant2)), | 1754 T.Union(T.ObjectConstant1, |
| 1781 T.Union(T.ObjectConstant2, T.ObjectConstant1)); | 1755 T.Union(T.ArrayConstant, T.ObjectConstant2))), |
| 1782 CheckEqual( | 1756 T.Union(T.ArrayConstant, |
| 1783 T.Intersect( | 1757 T.Union(T.ObjectConstant2, T.ObjectConstant1))); // !!! |
| 1784 T.Union( | |
| 1785 T.ArrayClass, | |
| 1786 T.Union(T.ObjectConstant2, T.ObjectConstant1)), | |
| 1787 T.Union( | |
| 1788 T.ObjectConstant1, | |
| 1789 T.Union(T.ArrayConstant, T.ObjectConstant2))), | |
| 1790 T.Union( | |
| 1791 T.ArrayConstant, | |
| 1792 T.Union(T.ObjectConstant2, T.ObjectConstant1))); // !!! | |
| 1793 } | 1758 } |
| 1794 | 1759 |
| 1795 void Distributivity() { | 1760 void Distributivity() { |
| 1796 // Union(T1, Intersect(T2, T3)) = Intersect(Union(T1, T2), Union(T1, T3)) | 1761 // Union(T1, Intersect(T2, T3)) = Intersect(Union(T1, T2), Union(T1, T3)) |
| 1797 // This does NOT hold. For example: | 1762 // This does NOT hold. For example: |
| 1798 // Untagged \/ (Untagged /\ Class(../Tagged)) = Untagged \/ Class(../Tagged) | 1763 // Untagged \/ (Untagged /\ Class(../Tagged)) = Untagged \/ Class(../Tagged) |
| 1799 // (Untagged \/ Untagged) /\ (Untagged \/ Class(../Tagged)) = | 1764 // (Untagged \/ Untagged) /\ (Untagged \/ Class(../Tagged)) = |
| 1800 // Untagged /\ (Untagged \/ Class(../Tagged)) = Untagged | 1765 // Untagged /\ (Untagged \/ Class(../Tagged)) = Untagged |
| 1801 // because Untagged <= Untagged \/ Class(../Tagged) | 1766 // because Untagged <= Untagged \/ Class(../Tagged) |
| 1802 /* | 1767 /* |
| 1803 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 1768 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1804 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 1769 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1805 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { | 1770 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { |
| 1806 Type* type1 = *it1; | 1771 AstType* type1 = *it1; |
| 1807 Type* type2 = *it2; | 1772 AstType* type2 = *it2; |
| 1808 Type* type3 = *it3; | 1773 AstType* type3 = *it3; |
| 1809 Type* union12 = T.Union(type1, type2); | 1774 AstType* union12 = T.Union(type1, type2); |
| 1810 Type* union13 = T.Union(type1, type3); | 1775 AstType* union13 = T.Union(type1, type3); |
| 1811 Type* intersect23 = T.Intersect(type2, type3); | 1776 AstType* intersect23 = T.Intersect(type2, type3); |
| 1812 Type* union1_23 = T.Union(type1, intersect23); | 1777 AstType* union1_23 = T.Union(type1, intersect23); |
| 1813 Type* intersect12_13 = T.Intersect(union12, union13); | 1778 AstType* intersect12_13 = T.Intersect(union12, union13); |
| 1814 CHECK(Equal(union1_23, intersect12_13)); | 1779 CHECK(Equal(union1_23, intersect12_13)); |
| 1815 } | 1780 } |
| 1816 } | 1781 } |
| 1817 } | 1782 } |
| 1818 */ | 1783 */ |
| 1819 | 1784 |
| 1820 // Intersect(T1, Union(T2, T3)) = Union(Intersect(T1, T2), Intersect(T1,T3)) | 1785 // Intersect(T1, Union(T2, T3)) = Union(Intersect(T1, T2), Intersect(T1,T3)) |
| 1821 // This does NOT hold. For example: | 1786 // This does NOT hold. For example: |
| 1822 // Untagged /\ (Untagged \/ Class(../Tagged)) = Untagged | 1787 // Untagged /\ (Untagged \/ Class(../Tagged)) = Untagged |
| 1823 // (Untagged /\ Untagged) \/ (Untagged /\ Class(../Tagged)) = | 1788 // (Untagged /\ Untagged) \/ (Untagged /\ Class(../Tagged)) = |
| 1824 // Untagged \/ Class(../Tagged) | 1789 // Untagged \/ Class(../Tagged) |
| 1825 /* | 1790 /* |
| 1826 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 1791 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1827 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 1792 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1828 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { | 1793 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { |
| 1829 Type* type1 = *it1; | 1794 AstType* type1 = *it1; |
| 1830 Type* type2 = *it2; | 1795 AstType* type2 = *it2; |
| 1831 Type* type3 = *it3; | 1796 AstType* type3 = *it3; |
| 1832 Type* intersect12 = T.Intersect(type1, type2); | 1797 AstType* intersect12 = T.Intersect(type1, type2); |
| 1833 Type* intersect13 = T.Intersect(type1, type3); | 1798 AstType* intersect13 = T.Intersect(type1, type3); |
| 1834 Type* union23 = T.Union(type2, type3); | 1799 AstType* union23 = T.Union(type2, type3); |
| 1835 Type* intersect1_23 = T.Intersect(type1, union23); | 1800 AstType* intersect1_23 = T.Intersect(type1, union23); |
| 1836 Type* union12_13 = T.Union(intersect12, intersect13); | 1801 AstType* union12_13 = T.Union(intersect12, intersect13); |
| 1837 CHECK(Equal(intersect1_23, union12_13)); | 1802 CHECK(Equal(intersect1_23, union12_13)); |
| 1838 } | 1803 } |
| 1839 } | 1804 } |
| 1840 } | 1805 } |
| 1841 */ | 1806 */ |
| 1842 } | 1807 } |
| 1843 | 1808 |
| 1844 void GetRange() { | 1809 void GetRange() { |
| 1845 // GetRange(Range(a, b)) = Range(a, b). | 1810 // GetRange(Range(a, b)) = Range(a, b). |
| 1846 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 1811 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1847 Type* type1 = *it1; | 1812 AstType* type1 = *it1; |
| 1848 if (type1->IsRange()) { | 1813 if (type1->IsRange()) { |
| 1849 RangeType* range = type1->GetRange()->AsRange(); | 1814 AstRangeType* range = type1->GetRange()->AsRange(); |
| 1850 CHECK(type1->Min() == range->Min()); | 1815 CHECK(type1->Min() == range->Min()); |
| 1851 CHECK(type1->Max() == range->Max()); | 1816 CHECK(type1->Max() == range->Max()); |
| 1852 } | 1817 } |
| 1853 } | 1818 } |
| 1854 | 1819 |
| 1855 // GetRange(Union(Constant(x), Range(min,max))) == Range(min, max). | 1820 // GetRange(Union(Constant(x), Range(min,max))) == Range(min, max). |
| 1856 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 1821 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1857 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 1822 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1858 Type* type1 = *it1; | 1823 AstType* type1 = *it1; |
| 1859 Type* type2 = *it2; | 1824 AstType* type2 = *it2; |
| 1860 if (type1->IsConstant() && type2->IsRange()) { | 1825 if (type1->IsConstant() && type2->IsRange()) { |
| 1861 Type* u = T.Union(type1, type2); | 1826 AstType* u = T.Union(type1, type2); |
| 1862 | 1827 |
| 1863 CHECK(type2->Min() == u->GetRange()->Min()); | 1828 CHECK(type2->Min() == u->GetRange()->Min()); |
| 1864 CHECK(type2->Max() == u->GetRange()->Max()); | 1829 CHECK(type2->Max() == u->GetRange()->Max()); |
| 1865 } | 1830 } |
| 1866 } | 1831 } |
| 1867 } | 1832 } |
| 1868 } | 1833 } |
| 1869 | 1834 |
| 1870 void HTypeFromType() { | 1835 void HTypeFromType() { |
| 1871 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 1836 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1872 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 1837 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1873 Type* type1 = *it1; | 1838 AstType* type1 = *it1; |
| 1874 Type* type2 = *it2; | 1839 AstType* type2 = *it2; |
| 1875 HType htype1 = HType::FromType(type1); | 1840 HType htype1 = HType::FromType(type1); |
| 1876 HType htype2 = HType::FromType(type2); | 1841 HType htype2 = HType::FromType(type2); |
| 1877 CHECK(!type1->Is(type2) || htype1.IsSubtypeOf(htype2)); | 1842 CHECK(!type1->Is(type2) || htype1.IsSubtypeOf(htype2)); |
| 1878 } | 1843 } |
| 1879 } | 1844 } |
| 1880 } | 1845 } |
| 1881 }; | 1846 }; |
| 1882 | 1847 |
| 1883 TEST(IsSomeType_zone) { Tests().IsSomeType(); } | 1848 TEST(AstIsSomeType_zone) { Tests().IsSomeType(); } |
| 1884 | 1849 |
| 1885 TEST(PointwiseRepresentation_zone) { Tests().PointwiseRepresentation(); } | 1850 TEST(AstPointwiseRepresentation_zone) { Tests().PointwiseRepresentation(); } |
| 1886 | 1851 |
| 1887 TEST(BitsetType_zone) { Tests().Bitset(); } | 1852 TEST(AstBitsetType_zone) { Tests().Bitset(); } |
| 1888 | 1853 |
| 1889 TEST(ClassType_zone) { Tests().Class(); } | 1854 TEST(AstClassType_zone) { Tests().Class(); } |
| 1890 | 1855 |
| 1891 TEST(ConstantType_zone) { Tests().Constant(); } | 1856 TEST(AstConstantType_zone) { Tests().Constant(); } |
| 1892 | 1857 |
| 1893 TEST(RangeType_zone) { Tests().Range(); } | 1858 TEST(AstRangeType_zone) { Tests().Range(); } |
| 1894 | 1859 |
| 1895 TEST(ArrayType_zone) { Tests().Array(); } | 1860 TEST(AstArrayType_zone) { Tests().Array(); } |
| 1896 | 1861 |
| 1897 TEST(FunctionType_zone) { Tests().Function(); } | 1862 TEST(AstFunctionType_zone) { Tests().Function(); } |
| 1898 | 1863 |
| 1899 TEST(Of_zone) { Tests().Of(); } | 1864 TEST(AstOf_zone) { Tests().Of(); } |
| 1900 | 1865 |
| 1901 TEST(NowOf_zone) { Tests().NowOf(); } | 1866 TEST(AstNowOf_zone) { Tests().NowOf(); } |
| 1902 | 1867 |
| 1903 TEST(MinMax_zone) { Tests().MinMax(); } | 1868 TEST(AstMinMax_zone) { Tests().MinMax(); } |
| 1904 | 1869 |
| 1905 TEST(BitsetGlb_zone) { Tests().BitsetGlb(); } | 1870 TEST(AstBitsetGlb_zone) { Tests().BitsetGlb(); } |
| 1906 | 1871 |
| 1907 TEST(BitsetLub_zone) { Tests().BitsetLub(); } | 1872 TEST(AstBitsetLub_zone) { Tests().BitsetLub(); } |
| 1908 | 1873 |
| 1909 TEST(Is1_zone) { Tests().Is1(); } | 1874 TEST(AstIs1_zone) { Tests().Is1(); } |
| 1910 | 1875 |
| 1911 TEST(Is2_zone) { Tests().Is2(); } | 1876 TEST(AstIs2_zone) { Tests().Is2(); } |
| 1912 | 1877 |
| 1913 TEST(NowIs_zone) { Tests().NowIs(); } | 1878 TEST(AstNowIs_zone) { Tests().NowIs(); } |
| 1914 | 1879 |
| 1915 TEST(Contains_zone) { Tests().Contains(); } | 1880 TEST(AstContains_zone) { Tests().Contains(); } |
| 1916 | 1881 |
| 1917 TEST(NowContains_zone) { Tests().NowContains(); } | 1882 TEST(AstNowContains_zone) { Tests().NowContains(); } |
| 1918 | 1883 |
| 1919 TEST(Maybe_zone) { Tests().Maybe(); } | 1884 TEST(AstMaybe_zone) { Tests().Maybe(); } |
| 1920 | 1885 |
| 1921 TEST(Union1_zone) { Tests().Union1(); } | 1886 TEST(AstUnion1_zone) { Tests().Union1(); } |
| 1922 | 1887 |
| 1923 TEST(Union2_zone) { Tests().Union2(); } | 1888 TEST(AstUnion2_zone) { Tests().Union2(); } |
| 1924 | 1889 |
| 1925 TEST(Union3_zone) { Tests().Union3(); } | 1890 TEST(AstUnion3_zone) { Tests().Union3(); } |
| 1926 | 1891 |
| 1927 TEST(Union4_zone) { Tests().Union4(); } | 1892 TEST(AstUnion4_zone) { Tests().Union4(); } |
| 1928 | 1893 |
| 1929 TEST(Intersect_zone) { Tests().Intersect(); } | 1894 TEST(AstIntersect_zone) { Tests().Intersect(); } |
| 1930 | 1895 |
| 1931 TEST(Distributivity_zone) { Tests().Distributivity(); } | 1896 TEST(AstDistributivity_zone) { Tests().Distributivity(); } |
| 1932 | 1897 |
| 1933 TEST(GetRange_zone) { Tests().GetRange(); } | 1898 TEST(AstGetRange_zone) { Tests().GetRange(); } |
| 1934 | 1899 |
| 1935 TEST(HTypeFromType_zone) { Tests().HTypeFromType(); } | 1900 TEST(AstHTypeFromType_zone) { Tests().HTypeFromType(); } |
| OLD | NEW |