| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <vector> | 5 #include <vector> |
| 6 | 6 |
| 7 #include "src/compiler/types.h" | 7 #include "src/compiler/types.h" |
| 8 #include "src/crankshaft/hydrogen-types.h" | 8 #include "src/crankshaft/hydrogen-types.h" |
| 9 #include "src/factory.h" | 9 #include "src/factory.h" |
| 10 #include "src/heap/heap.h" | 10 #include "src/heap/heap.h" |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 | 24 |
| 25 namespace { | 25 namespace { |
| 26 | 26 |
| 27 // Testing auxiliaries (breaking the Type abstraction). | 27 // Testing auxiliaries (breaking the Type abstraction). |
| 28 | 28 |
| 29 | 29 |
| 30 static bool IsInteger(double x) { | 30 static bool IsInteger(double x) { |
| 31 return nearbyint(x) == x && !i::IsMinusZero(x); // Allows for infinities. | 31 return nearbyint(x) == x && !i::IsMinusZero(x); // Allows for infinities. |
| 32 } | 32 } |
| 33 | 33 |
| 34 | |
| 35 static bool IsInteger(i::Object* x) { | |
| 36 return x->IsNumber() && IsInteger(x->Number()); | |
| 37 } | |
| 38 | |
| 39 | |
| 40 typedef uint32_t bitset; | 34 typedef uint32_t bitset; |
| 41 | 35 |
| 42 struct Tests { | 36 struct Tests { |
| 43 typedef Types::TypeVector::iterator TypeIterator; | 37 typedef Types::TypeVector::iterator TypeIterator; |
| 44 typedef Types::ValueVector::iterator ValueIterator; | 38 typedef Types::ValueVector::iterator ValueIterator; |
| 45 | 39 |
| 46 Isolate* isolate; | 40 Isolate* isolate; |
| 47 HandleScope scope; | 41 HandleScope scope; |
| 48 Zone zone; | 42 Zone zone; |
| 49 Types T; | 43 Types T; |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 106 CHECK(!type1->Is(type2)); | 100 CHECK(!type1->Is(type2)); |
| 107 CHECK(!type2->Is(type1)); | 101 CHECK(!type2->Is(type1)); |
| 108 CHECK(!type1->Maybe(type2)); | 102 CHECK(!type1->Maybe(type2)); |
| 109 CHECK(!type2->Maybe(type1)); | 103 CHECK(!type2->Maybe(type1)); |
| 110 } | 104 } |
| 111 | 105 |
| 112 void IsSomeType() { | 106 void IsSomeType() { |
| 113 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 107 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 114 Type* t = *it; | 108 Type* t = *it; |
| 115 CHECK(1 == | 109 CHECK(1 == |
| 116 this->IsBitset(t) + t->IsConstant() + t->IsRange() + | 110 this->IsBitset(t) + t->IsHeapConstant() + t->IsRange() + |
| 117 this->IsUnion(t)); | 111 t->IsOtherNumberConstant() + this->IsUnion(t)); |
| 118 } | 112 } |
| 119 } | 113 } |
| 120 | 114 |
| 121 void Bitset() { | 115 void Bitset() { |
| 122 // None and Any are bitsets. | 116 // None and Any are bitsets. |
| 123 CHECK(this->IsBitset(T.None)); | 117 CHECK(this->IsBitset(T.None)); |
| 124 CHECK(this->IsBitset(T.Any)); | 118 CHECK(this->IsBitset(T.Any)); |
| 125 | 119 |
| 126 CHECK(bitset(0) == this->AsBitset(T.None)); | 120 CHECK(bitset(0) == this->AsBitset(T.None)); |
| 127 CHECK(bitset(0xfffffffeu) == this->AsBitset(T.Any)); | 121 CHECK(bitset(0xfffffffeu) == this->AsBitset(T.Any)); |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 184 CHECK(bits == this->AsBitset(intersect12)); | 178 CHECK(bits == this->AsBitset(intersect12)); |
| 185 } | 179 } |
| 186 } | 180 } |
| 187 } | 181 } |
| 188 } | 182 } |
| 189 | 183 |
| 190 void Constant() { | 184 void Constant() { |
| 191 // Constructor | 185 // Constructor |
| 192 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 186 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
| 193 Handle<i::Object> value = *vt; | 187 Handle<i::Object> value = *vt; |
| 194 Type* type = T.Constant(value); | 188 Type* type = T.NewConstant(value); |
| 195 CHECK(type->IsConstant()); | 189 CHECK(type->IsHeapConstant() || type->IsOtherNumberConstant() || |
| 190 type->IsRange()); |
| 196 } | 191 } |
| 197 | 192 |
| 198 // Value attribute | 193 // Value attribute |
| 199 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 194 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
| 200 Handle<i::Object> value = *vt; | 195 Handle<i::Object> value = *vt; |
| 201 Type* type = T.Constant(value); | 196 Type* type = T.NewConstant(value); |
| 202 CHECK(*value == *type->AsConstant()->Value()); | 197 if (type->IsHeapConstant()) { |
| 198 CHECK(*value == *type->AsHeapConstant()->Value()); |
| 199 } else if (type->IsOtherNumberConstant()) { |
| 200 CHECK(value->IsHeapNumber()); |
| 201 CHECK(value->Number() == type->AsOtherNumberConstant()->Value()); |
| 202 } else { |
| 203 CHECK(type->IsRange()); |
| 204 double v = value->Number(); |
| 205 CHECK(v == type->AsRange()->Min() && v == type->AsRange()->Max()); |
| 206 } |
| 203 } | 207 } |
| 204 | 208 |
| 205 // Functionality & Injectivity: Constant(V1) = Constant(V2) iff V1 = V2 | 209 // Functionality & Injectivity: Constant(V1) = Constant(V2) iff V1 = V2 |
| 206 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) { | 210 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) { |
| 207 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) { | 211 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) { |
| 208 Handle<i::Object> value1 = *vt1; | 212 Handle<i::Object> value1 = *vt1; |
| 209 Handle<i::Object> value2 = *vt2; | 213 Handle<i::Object> value2 = *vt2; |
| 210 Type* type1 = T.Constant(value1); | 214 Type* type1 = T.NewConstant(value1); |
| 211 Type* type2 = T.Constant(value2); | 215 Type* type2 = T.NewConstant(value2); |
| 212 CHECK(Equal(type1, type2) == (*value1 == *value2)); | 216 if (type1->IsOtherNumberConstant() && type2->IsOtherNumberConstant()) { |
| 217 CHECK(Equal(type1, type2) == |
| 218 (type1->AsOtherNumberConstant()->Value() == |
| 219 type2->AsOtherNumberConstant()->Value())); |
| 220 } else if (type1->IsRange() && type2->IsRange()) { |
| 221 CHECK(Equal(type1, type2) == |
| 222 ((type1->AsRange()->Min() == type2->AsRange()->Min()) && |
| 223 (type1->AsRange()->Max() == type2->AsRange()->Max()))); |
| 224 } else { |
| 225 CHECK(Equal(type1, type2) == (*value1 == *value2)); |
| 226 } |
| 213 } | 227 } |
| 214 } | 228 } |
| 215 | 229 |
| 216 // Typing of numbers | 230 // Typing of numbers |
| 217 Factory* fac = isolate->factory(); | 231 Factory* fac = isolate->factory(); |
| 218 CHECK(T.Constant(fac->NewNumber(0))->Is(T.UnsignedSmall)); | 232 CHECK(T.NewConstant(fac->NewNumber(0))->Is(T.UnsignedSmall)); |
| 219 CHECK(T.Constant(fac->NewNumber(1))->Is(T.UnsignedSmall)); | 233 CHECK(T.NewConstant(fac->NewNumber(1))->Is(T.UnsignedSmall)); |
| 220 CHECK(T.Constant(fac->NewNumber(0x3fffffff))->Is(T.UnsignedSmall)); | 234 CHECK(T.NewConstant(fac->NewNumber(0x3fffffff))->Is(T.UnsignedSmall)); |
| 221 CHECK(T.Constant(fac->NewNumber(-1))->Is(T.Negative31)); | 235 CHECK(T.NewConstant(fac->NewNumber(-1))->Is(T.Negative31)); |
| 222 CHECK(T.Constant(fac->NewNumber(-0x3fffffff))->Is(T.Negative31)); | 236 CHECK(T.NewConstant(fac->NewNumber(-0x3fffffff))->Is(T.Negative31)); |
| 223 CHECK(T.Constant(fac->NewNumber(-0x40000000))->Is(T.Negative31)); | 237 CHECK(T.NewConstant(fac->NewNumber(-0x40000000))->Is(T.Negative31)); |
| 224 CHECK(T.Constant(fac->NewNumber(0x40000000))->Is(T.Unsigned31)); | 238 CHECK(T.NewConstant(fac->NewNumber(0x40000000))->Is(T.Unsigned31)); |
| 225 CHECK(!T.Constant(fac->NewNumber(0x40000000))->Is(T.Unsigned30)); | 239 CHECK(!T.NewConstant(fac->NewNumber(0x40000000))->Is(T.Unsigned30)); |
| 226 CHECK(T.Constant(fac->NewNumber(0x7fffffff))->Is(T.Unsigned31)); | 240 CHECK(T.NewConstant(fac->NewNumber(0x7fffffff))->Is(T.Unsigned31)); |
| 227 CHECK(!T.Constant(fac->NewNumber(0x7fffffff))->Is(T.Unsigned30)); | 241 CHECK(!T.NewConstant(fac->NewNumber(0x7fffffff))->Is(T.Unsigned30)); |
| 228 CHECK(T.Constant(fac->NewNumber(-0x40000001))->Is(T.Negative32)); | 242 CHECK(T.NewConstant(fac->NewNumber(-0x40000001))->Is(T.Negative32)); |
| 229 CHECK(!T.Constant(fac->NewNumber(-0x40000001))->Is(T.Negative31)); | 243 CHECK(!T.NewConstant(fac->NewNumber(-0x40000001))->Is(T.Negative31)); |
| 230 CHECK(T.Constant(fac->NewNumber(-0x7fffffff))->Is(T.Negative32)); | 244 CHECK(T.NewConstant(fac->NewNumber(-0x7fffffff))->Is(T.Negative32)); |
| 231 CHECK(!T.Constant(fac->NewNumber(-0x7fffffff - 1))->Is(T.Negative31)); | 245 CHECK(!T.NewConstant(fac->NewNumber(-0x7fffffff - 1))->Is(T.Negative31)); |
| 232 if (SmiValuesAre31Bits()) { | 246 if (SmiValuesAre31Bits()) { |
| 233 CHECK(!T.Constant(fac->NewNumber(0x40000000))->Is(T.UnsignedSmall)); | 247 CHECK(!T.NewConstant(fac->NewNumber(0x40000000))->Is(T.UnsignedSmall)); |
| 234 CHECK(!T.Constant(fac->NewNumber(0x7fffffff))->Is(T.UnsignedSmall)); | 248 CHECK(!T.NewConstant(fac->NewNumber(0x7fffffff))->Is(T.UnsignedSmall)); |
| 235 CHECK(!T.Constant(fac->NewNumber(-0x40000001))->Is(T.SignedSmall)); | 249 CHECK(!T.NewConstant(fac->NewNumber(-0x40000001))->Is(T.SignedSmall)); |
| 236 CHECK(!T.Constant(fac->NewNumber(-0x7fffffff - 1))->Is(T.SignedSmall)); | 250 CHECK(!T.NewConstant(fac->NewNumber(-0x7fffffff - 1))->Is(T.SignedSmall)); |
| 237 } else { | 251 } else { |
| 238 CHECK(SmiValuesAre32Bits()); | 252 CHECK(SmiValuesAre32Bits()); |
| 239 CHECK(T.Constant(fac->NewNumber(0x40000000))->Is(T.UnsignedSmall)); | 253 CHECK(T.NewConstant(fac->NewNumber(0x40000000))->Is(T.UnsignedSmall)); |
| 240 CHECK(T.Constant(fac->NewNumber(0x7fffffff))->Is(T.UnsignedSmall)); | 254 CHECK(T.NewConstant(fac->NewNumber(0x7fffffff))->Is(T.UnsignedSmall)); |
| 241 CHECK(T.Constant(fac->NewNumber(-0x40000001))->Is(T.SignedSmall)); | 255 CHECK(T.NewConstant(fac->NewNumber(-0x40000001))->Is(T.SignedSmall)); |
| 242 CHECK(T.Constant(fac->NewNumber(-0x7fffffff - 1))->Is(T.SignedSmall)); | 256 CHECK(T.NewConstant(fac->NewNumber(-0x7fffffff - 1))->Is(T.SignedSmall)); |
| 243 } | 257 } |
| 244 CHECK(T.Constant(fac->NewNumber(0x80000000u))->Is(T.Unsigned32)); | 258 CHECK(T.NewConstant(fac->NewNumber(0x80000000u))->Is(T.Unsigned32)); |
| 245 CHECK(!T.Constant(fac->NewNumber(0x80000000u))->Is(T.Unsigned31)); | 259 CHECK(!T.NewConstant(fac->NewNumber(0x80000000u))->Is(T.Unsigned31)); |
| 246 CHECK(T.Constant(fac->NewNumber(0xffffffffu))->Is(T.Unsigned32)); | 260 CHECK(T.NewConstant(fac->NewNumber(0xffffffffu))->Is(T.Unsigned32)); |
| 247 CHECK(!T.Constant(fac->NewNumber(0xffffffffu))->Is(T.Unsigned31)); | 261 CHECK(!T.NewConstant(fac->NewNumber(0xffffffffu))->Is(T.Unsigned31)); |
| 248 CHECK(T.Constant(fac->NewNumber(0xffffffffu + 1.0))->Is(T.PlainNumber)); | 262 CHECK(T.NewConstant(fac->NewNumber(0xffffffffu + 1.0))->Is(T.PlainNumber)); |
| 249 CHECK(!T.Constant(fac->NewNumber(0xffffffffu + 1.0))->Is(T.Integral32)); | 263 CHECK(!T.NewConstant(fac->NewNumber(0xffffffffu + 1.0))->Is(T.Integral32)); |
| 250 CHECK(T.Constant(fac->NewNumber(-0x7fffffff - 2.0))->Is(T.PlainNumber)); | 264 CHECK(T.NewConstant(fac->NewNumber(-0x7fffffff - 2.0))->Is(T.PlainNumber)); |
| 251 CHECK(!T.Constant(fac->NewNumber(-0x7fffffff - 2.0))->Is(T.Integral32)); | 265 CHECK(!T.NewConstant(fac->NewNumber(-0x7fffffff - 2.0))->Is(T.Integral32)); |
| 252 CHECK(T.Constant(fac->NewNumber(0.1))->Is(T.PlainNumber)); | 266 CHECK(T.NewConstant(fac->NewNumber(0.1))->Is(T.PlainNumber)); |
| 253 CHECK(!T.Constant(fac->NewNumber(0.1))->Is(T.Integral32)); | 267 CHECK(!T.NewConstant(fac->NewNumber(0.1))->Is(T.Integral32)); |
| 254 CHECK(T.Constant(fac->NewNumber(-10.1))->Is(T.PlainNumber)); | 268 CHECK(T.NewConstant(fac->NewNumber(-10.1))->Is(T.PlainNumber)); |
| 255 CHECK(!T.Constant(fac->NewNumber(-10.1))->Is(T.Integral32)); | 269 CHECK(!T.NewConstant(fac->NewNumber(-10.1))->Is(T.Integral32)); |
| 256 CHECK(T.Constant(fac->NewNumber(10e60))->Is(T.PlainNumber)); | 270 CHECK(T.NewConstant(fac->NewNumber(10e60))->Is(T.PlainNumber)); |
| 257 CHECK(!T.Constant(fac->NewNumber(10e60))->Is(T.Integral32)); | 271 CHECK(!T.NewConstant(fac->NewNumber(10e60))->Is(T.Integral32)); |
| 258 CHECK(T.Constant(fac->NewNumber(-1.0*0.0))->Is(T.MinusZero)); | 272 CHECK(T.NewConstant(fac->NewNumber(-1.0 * 0.0))->Is(T.MinusZero)); |
| 259 CHECK(T.Constant(fac->NewNumber(std::numeric_limits<double>::quiet_NaN())) | 273 CHECK( |
| 260 ->Is(T.NaN)); | 274 T.NewConstant(fac->NewNumber(std::numeric_limits<double>::quiet_NaN())) |
| 261 CHECK(T.Constant(fac->NewNumber(V8_INFINITY))->Is(T.PlainNumber)); | 275 ->Is(T.NaN)); |
| 262 CHECK(!T.Constant(fac->NewNumber(V8_INFINITY))->Is(T.Integral32)); | 276 CHECK(T.NewConstant(fac->NewNumber(V8_INFINITY))->Is(T.PlainNumber)); |
| 263 CHECK(T.Constant(fac->NewNumber(-V8_INFINITY))->Is(T.PlainNumber)); | 277 CHECK(!T.NewConstant(fac->NewNumber(V8_INFINITY))->Is(T.Integral32)); |
| 264 CHECK(!T.Constant(fac->NewNumber(-V8_INFINITY))->Is(T.Integral32)); | 278 CHECK(T.NewConstant(fac->NewNumber(-V8_INFINITY))->Is(T.PlainNumber)); |
| 279 CHECK(!T.NewConstant(fac->NewNumber(-V8_INFINITY))->Is(T.Integral32)); |
| 265 } | 280 } |
| 266 | 281 |
| 267 void Range() { | 282 void Range() { |
| 268 // Constructor | 283 // Constructor |
| 269 for (ValueIterator i = T.integers.begin(); i != T.integers.end(); ++i) { | 284 for (ValueIterator i = T.integers.begin(); i != T.integers.end(); ++i) { |
| 270 for (ValueIterator j = T.integers.begin(); j != T.integers.end(); ++j) { | 285 for (ValueIterator j = T.integers.begin(); j != T.integers.end(); ++j) { |
| 271 double min = (*i)->Number(); | 286 double min = (*i)->Number(); |
| 272 double max = (*j)->Number(); | 287 double max = (*j)->Number(); |
| 273 if (min > max) std::swap(min, max); | 288 if (min > max) std::swap(min, max); |
| 274 Type* type = T.Range(min, max); | 289 Type* type = T.Range(min, max); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 310 } | 325 } |
| 311 } | 326 } |
| 312 } | 327 } |
| 313 } | 328 } |
| 314 } | 329 } |
| 315 | 330 |
| 316 void Of() { | 331 void Of() { |
| 317 // Constant(V)->Is(Of(V)) | 332 // Constant(V)->Is(Of(V)) |
| 318 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 333 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
| 319 Handle<i::Object> value = *vt; | 334 Handle<i::Object> value = *vt; |
| 320 Type* const_type = T.Constant(value); | 335 Type* const_type = T.NewConstant(value); |
| 321 Type* of_type = T.Of(value); | 336 Type* of_type = T.Of(value); |
| 322 CHECK(const_type->Is(of_type)); | 337 CHECK(const_type->Is(of_type)); |
| 323 } | 338 } |
| 324 | 339 |
| 325 // If Of(V)->Is(T), then Constant(V)->Is(T) | 340 // If Of(V)->Is(T), then Constant(V)->Is(T) |
| 326 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 341 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
| 327 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 342 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 328 Handle<i::Object> value = *vt; | 343 Handle<i::Object> value = *vt; |
| 329 Type* type = *it; | 344 Type* type = *it; |
| 330 Type* const_type = T.Constant(value); | 345 Type* const_type = T.NewConstant(value); |
| 331 Type* of_type = T.Of(value); | 346 Type* of_type = T.Of(value); |
| 332 CHECK(!of_type->Is(type) || const_type->Is(type)); | 347 CHECK(!of_type->Is(type) || const_type->Is(type)); |
| 333 } | 348 } |
| 334 } | 349 } |
| 335 | 350 |
| 336 // If Constant(V)->Is(T), then Of(V)->Is(T) or T->Maybe(Constant(V)) | 351 // If Constant(V)->Is(T), then Of(V)->Is(T) or T->Maybe(Constant(V)) |
| 337 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 352 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
| 338 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 353 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 339 Handle<i::Object> value = *vt; | 354 Handle<i::Object> value = *vt; |
| 340 Type* type = *it; | 355 Type* type = *it; |
| 341 Type* const_type = T.Constant(value); | 356 Type* const_type = T.NewConstant(value); |
| 342 Type* of_type = T.Of(value); | 357 Type* of_type = T.Of(value); |
| 343 CHECK(!const_type->Is(type) || | 358 CHECK(!const_type->Is(type) || |
| 344 of_type->Is(type) || type->Maybe(const_type)); | 359 of_type->Is(type) || type->Maybe(const_type)); |
| 345 } | 360 } |
| 346 } | 361 } |
| 347 } | 362 } |
| 348 | 363 |
| 349 void MinMax() { | 364 void MinMax() { |
| 350 // If b is regular numeric bitset, then Range(b->Min(), b->Max())->Is(b). | 365 // If b is regular numeric bitset, then Range(b->Min(), b->Max())->Is(b). |
| 351 // TODO(neis): Need to ignore representation for this to be true. | 366 // TODO(neis): Need to ignore representation for this to be true. |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 514 } | 529 } |
| 515 } | 530 } |
| 516 | 531 |
| 517 // (In-)Compatibilities. | 532 // (In-)Compatibilities. |
| 518 for (TypeIterator i = T.types.begin(); i != T.types.end(); ++i) { | 533 for (TypeIterator i = T.types.begin(); i != T.types.end(); ++i) { |
| 519 for (TypeIterator j = T.types.begin(); j != T.types.end(); ++j) { | 534 for (TypeIterator j = T.types.begin(); j != T.types.end(); ++j) { |
| 520 Type* type1 = *i; | 535 Type* type1 = *i; |
| 521 Type* type2 = *j; | 536 Type* type2 = *j; |
| 522 CHECK(!type1->Is(type2) || this->IsBitset(type2) || | 537 CHECK(!type1->Is(type2) || this->IsBitset(type2) || |
| 523 this->IsUnion(type2) || this->IsUnion(type1) || | 538 this->IsUnion(type2) || this->IsUnion(type1) || |
| 524 (type1->IsConstant() && type2->IsConstant()) || | 539 (type1->IsHeapConstant() && type2->IsHeapConstant()) || |
| 525 (type1->IsConstant() && type2->IsRange()) || | |
| 526 (this->IsBitset(type1) && type2->IsRange()) || | 540 (this->IsBitset(type1) && type2->IsRange()) || |
| 527 (type1->IsRange() && type2->IsRange()) || | 541 (type1->IsRange() && type2->IsRange()) || |
| 542 (type1->IsOtherNumberConstant() && |
| 543 type2->IsOtherNumberConstant()) || |
| 528 !type1->IsInhabited()); | 544 !type1->IsInhabited()); |
| 529 } | 545 } |
| 530 } | 546 } |
| 531 } | 547 } |
| 532 | 548 |
| 533 void Is2() { | 549 void Is2() { |
| 534 // Range(X1, Y1)->Is(Range(X2, Y2)) iff X1 >= X2 /\ Y1 <= Y2 | 550 // Range(X1, Y1)->Is(Range(X2, Y2)) iff X1 >= X2 /\ Y1 <= Y2 |
| 535 for (ValueIterator i1 = T.integers.begin(); | 551 for (ValueIterator i1 = T.integers.begin(); |
| 536 i1 != T.integers.end(); ++i1) { | 552 i1 != T.integers.end(); ++i1) { |
| 537 for (ValueIterator j1 = i1; | 553 for (ValueIterator j1 = i1; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 552 } | 568 } |
| 553 } | 569 } |
| 554 } | 570 } |
| 555 } | 571 } |
| 556 | 572 |
| 557 // Constant(V1)->Is(Constant(V2)) iff V1 = V2 | 573 // Constant(V1)->Is(Constant(V2)) iff V1 = V2 |
| 558 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) { | 574 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) { |
| 559 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) { | 575 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) { |
| 560 Handle<i::Object> value1 = *vt1; | 576 Handle<i::Object> value1 = *vt1; |
| 561 Handle<i::Object> value2 = *vt2; | 577 Handle<i::Object> value2 = *vt2; |
| 562 Type* const_type1 = T.Constant(value1); | 578 Type* const_type1 = T.NewConstant(value1); |
| 563 Type* const_type2 = T.Constant(value2); | 579 Type* const_type2 = T.NewConstant(value2); |
| 564 CHECK(const_type1->Is(const_type2) == (*value1 == *value2)); | 580 if (const_type1->IsOtherNumberConstant() && |
| 581 const_type2->IsOtherNumberConstant()) { |
| 582 CHECK(const_type1->Is(const_type2) == |
| 583 (const_type1->AsOtherNumberConstant()->Value() == |
| 584 const_type2->AsOtherNumberConstant()->Value())); |
| 585 } else if (const_type1->IsRange() && const_type2->IsRange()) { |
| 586 CHECK(Equal(const_type1, const_type2) == |
| 587 ((const_type1->AsRange()->Min() == |
| 588 const_type2->AsRange()->Min()) && |
| 589 (const_type1->AsRange()->Max() == |
| 590 const_type2->AsRange()->Max()))); |
| 591 } else { |
| 592 CHECK(const_type1->Is(const_type2) == (*value1 == *value2)); |
| 593 } |
| 565 } | 594 } |
| 566 } | 595 } |
| 567 | 596 |
| 568 // Range-specific subtyping | 597 // Range-specific subtyping |
| 569 | 598 |
| 570 // If IsInteger(v) then Constant(v)->Is(Range(v, v)). | |
| 571 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | |
| 572 Type* type = *it; | |
| 573 if (type->IsConstant() && IsInteger(*type->AsConstant()->Value())) { | |
| 574 CHECK(type->Is(T.Range(type->AsConstant()->Value()->Number(), | |
| 575 type->AsConstant()->Value()->Number()))); | |
| 576 } | |
| 577 } | |
| 578 | |
| 579 // If Constant(x)->Is(Range(min,max)) then IsInteger(v) and min <= x <= max. | |
| 580 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | |
| 581 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | |
| 582 Type* type1 = *it1; | |
| 583 Type* type2 = *it2; | |
| 584 if (type1->IsConstant() && type2->IsRange() && type1->Is(type2)) { | |
| 585 double x = type1->AsConstant()->Value()->Number(); | |
| 586 double min = type2->AsRange()->Min(); | |
| 587 double max = type2->AsRange()->Max(); | |
| 588 CHECK(IsInteger(x) && min <= x && x <= max); | |
| 589 } | |
| 590 } | |
| 591 } | |
| 592 | |
| 593 // Lub(Range(x,y))->Is(T.Union(T.Integral32, T.OtherNumber)) | 599 // Lub(Range(x,y))->Is(T.Union(T.Integral32, T.OtherNumber)) |
| 594 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 600 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 595 Type* type = *it; | 601 Type* type = *it; |
| 596 if (type->IsRange()) { | 602 if (type->IsRange()) { |
| 597 Type* lub = BitsetType::NewForTesting(BitsetType::Lub(type)); | 603 Type* lub = BitsetType::NewForTesting(BitsetType::Lub(type)); |
| 598 CHECK(lub->Is(T.PlainNumber)); | 604 CHECK(lub->Is(T.PlainNumber)); |
| 599 } | 605 } |
| 600 } | 606 } |
| 601 | 607 |
| 602 | 608 |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 705 CHECK(!(type1->Is(type2) && type1->IsInhabited()) || | 711 CHECK(!(type1->Is(type2) && type1->IsInhabited()) || |
| 706 type1->Maybe(type2)); | 712 type1->Maybe(type2)); |
| 707 } | 713 } |
| 708 } | 714 } |
| 709 | 715 |
| 710 // Constant(V1)->Maybe(Constant(V2)) iff V1 = V2 | 716 // Constant(V1)->Maybe(Constant(V2)) iff V1 = V2 |
| 711 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) { | 717 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) { |
| 712 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) { | 718 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) { |
| 713 Handle<i::Object> value1 = *vt1; | 719 Handle<i::Object> value1 = *vt1; |
| 714 Handle<i::Object> value2 = *vt2; | 720 Handle<i::Object> value2 = *vt2; |
| 715 Type* const_type1 = T.Constant(value1); | 721 Type* const_type1 = T.NewConstant(value1); |
| 716 Type* const_type2 = T.Constant(value2); | 722 Type* const_type2 = T.NewConstant(value2); |
| 717 CHECK(const_type1->Maybe(const_type2) == (*value1 == *value2)); | 723 if (const_type1->IsOtherNumberConstant() && |
| 724 const_type2->IsOtherNumberConstant()) { |
| 725 CHECK(const_type1->Maybe(const_type2) == |
| 726 (const_type1->AsOtherNumberConstant()->Value() == |
| 727 const_type2->AsOtherNumberConstant()->Value())); |
| 728 } else if (const_type1->IsRange() && const_type2->IsRange()) { |
| 729 CHECK(Equal(const_type1, const_type2) == |
| 730 ((const_type1->AsRange()->Min() == |
| 731 const_type2->AsRange()->Min()) && |
| 732 (const_type1->AsRange()->Max() == |
| 733 const_type2->AsRange()->Max()))); |
| 734 } else { |
| 735 CHECK(const_type1->Maybe(const_type2) == (*value1 == *value2)); |
| 736 } |
| 718 } | 737 } |
| 719 } | 738 } |
| 720 | 739 |
| 721 // Basic types | 740 // Basic types |
| 722 CheckDisjoint(T.Boolean, T.Null); | 741 CheckDisjoint(T.Boolean, T.Null); |
| 723 CheckDisjoint(T.Undefined, T.Null); | 742 CheckDisjoint(T.Undefined, T.Null); |
| 724 CheckDisjoint(T.Boolean, T.Undefined); | 743 CheckDisjoint(T.Boolean, T.Undefined); |
| 725 CheckOverlap(T.SignedSmall, T.Number); | 744 CheckOverlap(T.SignedSmall, T.Number); |
| 726 CheckOverlap(T.NaN, T.Number); | 745 CheckOverlap(T.NaN, T.Number); |
| 727 CheckDisjoint(T.Signed32, T.NaN); | 746 CheckDisjoint(T.Signed32, T.NaN); |
| (...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1047 void GetRange() { | 1066 void GetRange() { |
| 1048 // GetRange(Range(a, b)) = Range(a, b). | 1067 // GetRange(Range(a, b)) = Range(a, b). |
| 1049 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 1068 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1050 Type* type1 = *it1; | 1069 Type* type1 = *it1; |
| 1051 if (type1->IsRange()) { | 1070 if (type1->IsRange()) { |
| 1052 RangeType* range = type1->GetRange()->AsRange(); | 1071 RangeType* range = type1->GetRange()->AsRange(); |
| 1053 CHECK(type1->Min() == range->Min()); | 1072 CHECK(type1->Min() == range->Min()); |
| 1054 CHECK(type1->Max() == range->Max()); | 1073 CHECK(type1->Max() == range->Max()); |
| 1055 } | 1074 } |
| 1056 } | 1075 } |
| 1057 | |
| 1058 // GetRange(Union(Constant(x), Range(min,max))) == Range(min, max). | |
| 1059 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | |
| 1060 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | |
| 1061 Type* type1 = *it1; | |
| 1062 Type* type2 = *it2; | |
| 1063 if (type1->IsConstant() && type2->IsRange()) { | |
| 1064 Type* u = T.Union(type1, type2); | |
| 1065 | |
| 1066 CHECK(type2->Min() == u->GetRange()->Min()); | |
| 1067 CHECK(type2->Max() == u->GetRange()->Max()); | |
| 1068 } | |
| 1069 } | |
| 1070 } | |
| 1071 } | 1076 } |
| 1072 }; | 1077 }; |
| 1073 | 1078 |
| 1074 } // namespace | 1079 } // namespace |
| 1075 | 1080 |
| 1076 TEST(IsSomeType) { Tests().IsSomeType(); } | 1081 TEST(IsSomeType) { Tests().IsSomeType(); } |
| 1077 | 1082 |
| 1078 TEST(BitsetType) { Tests().Bitset(); } | 1083 TEST(BitsetType) { Tests().Bitset(); } |
| 1079 | 1084 |
| 1080 TEST(ConstantType) { Tests().Constant(); } | 1085 TEST(ConstantType) { Tests().Constant(); } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1101 | 1106 |
| 1102 TEST(Union3) { Tests().Union3(); } | 1107 TEST(Union3) { Tests().Union3(); } |
| 1103 | 1108 |
| 1104 TEST(Union4) { Tests().Union4(); } | 1109 TEST(Union4) { Tests().Union4(); } |
| 1105 | 1110 |
| 1106 TEST(Intersect) { Tests().Intersect(); } | 1111 TEST(Intersect) { Tests().Intersect(); } |
| 1107 | 1112 |
| 1108 TEST(Distributivity) { Tests().Distributivity(); } | 1113 TEST(Distributivity) { Tests().Distributivity(); } |
| 1109 | 1114 |
| 1110 TEST(GetRange) { Tests().GetRange(); } | 1115 TEST(GetRange) { Tests().GetRange(); } |
| OLD | NEW |