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