Chromium Code Reviews| 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/hydrogen-types.h" | 7 #include "src/hydrogen-types.h" |
| 8 #include "src/isolate-inl.h" | 8 #include "src/isolate-inl.h" |
| 9 #include "src/types.h" | 9 #include "src/types.h" |
| 10 #include "test/cctest/cctest.h" | 10 #include "test/cctest/cctest.h" |
| 11 | 11 |
| 12 using namespace v8::internal; | 12 using namespace v8::internal; |
| 13 | 13 |
| 14 | |
| 14 // Testing auxiliaries (breaking the Type abstraction). | 15 // Testing auxiliaries (breaking the Type abstraction). |
| 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 | |
| 15 typedef uint32_t bitset; | 28 typedef uint32_t bitset; |
| 16 | 29 |
| 30 | |
| 17 struct ZoneRep { | 31 struct ZoneRep { |
| 18 typedef void* Struct; | 32 typedef void* Struct; |
| 19 | 33 |
| 20 static bool IsStruct(Type* t, int tag) { | 34 static bool IsStruct(Type* t, int tag) { |
| 21 return !IsBitset(t) && reinterpret_cast<intptr_t>(AsStruct(t)[0]) == tag; | 35 return !IsBitset(t) && reinterpret_cast<intptr_t>(AsStruct(t)[0]) == tag; |
| 22 } | 36 } |
| 23 static bool IsBitset(Type* t) { return reinterpret_cast<uintptr_t>(t) & 1; } | 37 static bool IsBitset(Type* t) { return reinterpret_cast<uintptr_t>(t) & 1; } |
| 24 static bool IsUnion(Type* t) { return IsStruct(t, 6); } | 38 static bool IsUnion(Type* t) { return IsStruct(t, 6); } |
| 25 | 39 |
| 26 static Struct* AsStruct(Type* t) { | 40 static Struct* AsStruct(Type* t) { |
| (...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 495 // Functionality & Injectivity: Class(M1) = Class(M2) iff M1 = M2 | 509 // Functionality & Injectivity: Class(M1) = Class(M2) iff M1 = M2 |
| 496 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) { | 510 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) { |
| 497 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) { | 511 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) { |
| 498 Handle<i::Map> map1 = *mt1; | 512 Handle<i::Map> map1 = *mt1; |
| 499 Handle<i::Map> map2 = *mt2; | 513 Handle<i::Map> map2 = *mt2; |
| 500 TypeHandle type1 = T.Class(map1); | 514 TypeHandle type1 = T.Class(map1); |
| 501 TypeHandle type2 = T.Class(map2); | 515 TypeHandle type2 = T.Class(map2); |
| 502 CHECK(Equal(type1, type2) == (*map1 == *map2)); | 516 CHECK(Equal(type1, type2) == (*map1 == *map2)); |
| 503 } | 517 } |
| 504 } | 518 } |
| 519 | |
| 520 // Subtyping: Class(M1)->Is(Class(M2)) iff M1 = M2 | |
|
rossberg
2014/09/24 12:59:09
Hm, I'd rather leave the subtyping tests where the
neis1
2014/09/24 15:12:08
I changed it back now. But if you look at e.g. Co
| |
| 521 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) { | |
| 522 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) { | |
| 523 Handle<i::Map> map1 = *mt1; | |
| 524 Handle<i::Map> map2 = *mt2; | |
| 525 TypeHandle class_type1 = T.Class(map1); | |
| 526 TypeHandle class_type2 = T.Class(map2); | |
| 527 CHECK(class_type1->Is(class_type2) == (*map1 == *map2)); | |
| 528 } | |
| 529 } | |
| 505 } | 530 } |
| 506 | 531 |
| 507 void Constant() { | 532 void Constant() { |
| 508 // Constructor | 533 // Constructor |
| 509 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 534 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
| 510 Handle<i::Object> value = *vt; | 535 Handle<i::Object> value = *vt; |
| 511 TypeHandle type = T.Constant(value); | 536 TypeHandle type = T.Constant(value); |
| 512 CHECK(type->IsConstant()); | 537 CHECK(type->IsConstant()); |
| 513 } | 538 } |
| 514 | 539 |
| 515 // Value attribute | 540 // Value attribute |
| 516 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 541 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
| 517 Handle<i::Object> value = *vt; | 542 Handle<i::Object> value = *vt; |
| 518 TypeHandle type = T.Constant(value); | 543 TypeHandle type = T.Constant(value); |
| 519 CHECK(*value == *type->AsConstant()->Value()); | 544 CHECK(*value == *type->AsConstant()->Value()); |
| 520 } | 545 } |
| 521 | 546 |
| 522 // Functionality & Injectivity: Constant(V1) = Constant(V2) iff V1 = V2 | 547 // Functionality & Injectivity: Constant(V1) = Constant(V2) iff V1 = V2 |
| 523 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) { | 548 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) { |
| 524 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) { | 549 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) { |
| 525 Handle<i::Object> value1 = *vt1; | 550 Handle<i::Object> value1 = *vt1; |
| 526 Handle<i::Object> value2 = *vt2; | 551 Handle<i::Object> value2 = *vt2; |
| 527 TypeHandle type1 = T.Constant(value1); | 552 TypeHandle type1 = T.Constant(value1); |
| 528 TypeHandle type2 = T.Constant(value2); | 553 TypeHandle type2 = T.Constant(value2); |
| 529 CHECK(Equal(type1, type2) == (*value1 == *value2)); | 554 CHECK(Equal(type1, type2) == (*value1 == *value2)); |
| 530 } | 555 } |
| 531 } | 556 } |
| 532 | 557 |
| 558 // Subtyping: Constant(V1)->Is(Constant(V2)) iff V1 = V2 | |
| 559 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) { | |
| 560 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) { | |
| 561 Handle<i::Object> value1 = *vt1; | |
| 562 Handle<i::Object> value2 = *vt2; | |
| 563 TypeHandle const_type1 = T.Constant(value1); | |
| 564 TypeHandle const_type2 = T.Constant(value2); | |
| 565 CHECK(const_type1->Is(const_type2) == (*value1 == *value2)); | |
| 566 } | |
| 567 } | |
| 568 | |
| 533 // Typing of numbers | 569 // Typing of numbers |
| 534 Factory* fac = isolate->factory(); | 570 Factory* fac = isolate->factory(); |
| 535 CHECK(T.Constant(fac->NewNumber(0))->Is(T.UnsignedSmall)); | 571 CHECK(T.Constant(fac->NewNumber(0))->Is(T.UnsignedSmall)); |
| 536 CHECK(T.Constant(fac->NewNumber(1))->Is(T.UnsignedSmall)); | 572 CHECK(T.Constant(fac->NewNumber(1))->Is(T.UnsignedSmall)); |
| 537 CHECK(T.Constant(fac->NewNumber(0x3fffffff))->Is(T.UnsignedSmall)); | 573 CHECK(T.Constant(fac->NewNumber(0x3fffffff))->Is(T.UnsignedSmall)); |
| 538 CHECK(T.Constant(fac->NewNumber(-1))->Is(T.OtherSignedSmall)); | 574 CHECK(T.Constant(fac->NewNumber(-1))->Is(T.OtherSignedSmall)); |
| 539 CHECK(T.Constant(fac->NewNumber(-0x3fffffff))->Is(T.OtherSignedSmall)); | 575 CHECK(T.Constant(fac->NewNumber(-0x3fffffff))->Is(T.OtherSignedSmall)); |
| 540 CHECK(T.Constant(fac->NewNumber(-0x40000000))->Is(T.OtherSignedSmall)); | 576 CHECK(T.Constant(fac->NewNumber(-0x40000000))->Is(T.OtherSignedSmall)); |
| 541 if (SmiValuesAre31Bits()) { | 577 if (SmiValuesAre31Bits()) { |
| 542 CHECK(T.Constant(fac->NewNumber(0x40000000))->Is(T.OtherUnsigned31)); | 578 CHECK(T.Constant(fac->NewNumber(0x40000000))->Is(T.OtherUnsigned31)); |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 610 i::Handle<i::Object> max2 = *j2; | 646 i::Handle<i::Object> max2 = *j2; |
| 611 if (min1->Number() > max1->Number()) std::swap(min1, max1); | 647 if (min1->Number() > max1->Number()) std::swap(min1, max1); |
| 612 if (min2->Number() > max2->Number()) std::swap(min2, max2); | 648 if (min2->Number() > max2->Number()) std::swap(min2, max2); |
| 613 TypeHandle type1 = T.Range(min1, max1); | 649 TypeHandle type1 = T.Range(min1, max1); |
| 614 TypeHandle type2 = T.Range(min2, max2); | 650 TypeHandle type2 = T.Range(min2, max2); |
| 615 CHECK(Equal(type1, type2) == (*min1 == *min2 && *max1 == *max2)); | 651 CHECK(Equal(type1, type2) == (*min1 == *min2 && *max1 == *max2)); |
| 616 } | 652 } |
| 617 } | 653 } |
| 618 } | 654 } |
| 619 } | 655 } |
| 656 | |
| 657 // Subtyping: | |
| 658 // Range(x1, y1)->Is(Range(x2, y2)) iff x1 >= x2 /\ y1 <= y2 | |
| 659 for (ValueIterator i1 = T.integers.begin(); | |
| 660 i1 != T.integers.end(); ++i1) { | |
| 661 for (ValueIterator j1 = i1; | |
| 662 j1 != T.integers.end(); ++j1) { | |
| 663 for (ValueIterator i2 = T.integers.begin(); | |
| 664 i2 != T.integers.end(); ++i2) { | |
| 665 for (ValueIterator j2 = i2; | |
| 666 j2 != T.integers.end(); ++j2) { | |
| 667 i::Handle<i::Object> min1 = *i1; | |
| 668 i::Handle<i::Object> max1 = *j1; | |
| 669 i::Handle<i::Object> min2 = *i2; | |
| 670 i::Handle<i::Object> max2 = *j2; | |
| 671 if (min1->Number() > max1->Number()) std::swap(min1, max1); | |
| 672 if (min2->Number() > max2->Number()) std::swap(min2, max2); | |
| 673 TypeHandle type1 = T.Range(min1, max1); | |
| 674 TypeHandle type2 = T.Range(min2, max2); | |
| 675 CHECK(type1->Is(type2) == | |
| 676 (min2->Number() <= min1->Number() && | |
| 677 max1->Number() <= max2->Number())); | |
| 678 } | |
| 679 } | |
| 680 } | |
| 681 } | |
| 682 | |
| 683 // Subtyping: If IsInteger(v) then Constant(v)->Is(Range(v, v)). | |
| 684 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | |
| 685 TypeHandle type = *it; | |
| 686 if (type->IsConstant() && IsInteger(*type->AsConstant()->Value())) { | |
| 687 CHECK(type->Is( | |
| 688 T.Range(type->AsConstant()->Value(), type->AsConstant()->Value()))); | |
| 689 } | |
| 690 } | |
| 691 | |
| 692 // If Constant(x)->Is(Range(min,max)) then IsInteger(v) and min <= x <= max. | |
| 693 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | |
| 694 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | |
| 695 TypeHandle type1 = *it1; | |
| 696 TypeHandle type2 = *it2; | |
| 697 if (type1->IsConstant() && type2->IsRange() && type1->Is(type2)) { | |
| 698 double x = type1->AsConstant()->Value()->Number(); | |
| 699 double min = type2->AsRange()->Min()->Number(); | |
| 700 double max = type2->AsRange()->Max()->Number(); | |
| 701 CHECK(IsInteger(x) && min <= x && x <= max); | |
| 702 } | |
| 703 } | |
| 704 } | |
| 705 | |
| 706 // Lub(Range(x,y))->Is(T.Union(T.Integral32, T.OtherNumber)) | |
| 707 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | |
| 708 TypeHandle type = *it; | |
| 709 if (type->IsRange()) { | |
| 710 TypeHandle lub = Rep::BitsetType::New( | |
| 711 Rep::BitsetType::Lub(type), T.region()); | |
| 712 CHECK(lub->Is(T.Union(T.Integral32, T.OtherNumber))); | |
| 713 } | |
| 714 } | |
| 715 | |
| 716 // If b is regular numberic bitset, then b->Min() and b->Max() are integers. | |
|
rossberg
2014/09/24 12:59:09
How about introducing a separate test MinMax for t
neis1
2014/09/24 15:12:08
Done.
| |
| 717 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | |
| 718 TypeHandle type = *it; | |
| 719 if (this->IsBitset(type) && type->Is(T.Number) && | |
| 720 !type->Is(T.None) && !type->Is(T.NaN)) { | |
| 721 CHECK(IsInteger(type->Min()) && IsInteger(type->Max())); | |
| 722 } | |
| 723 } | |
| 724 | |
| 725 // If b is regular numberic bitset, then Range(b->Min(), b->Max())->Is(b). | |
|
rossberg
2014/09/24 12:59:09
Typo
neis1
2014/09/24 15:12:08
Done.
| |
| 726 // TODO(neis): Need to ignore representation for this to be true. | |
| 727 /* | |
| 728 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | |
| 729 TypeHandle type = *it; | |
| 730 if (this->IsBitset(type) && type->Is(T.Number) && | |
| 731 !type->Is(T.None) && !type->Is(T.NaN)) { | |
| 732 TypeHandle range = T.Range( | |
| 733 isolate->factory()->NewNumber(type->Min()), | |
| 734 isolate->factory()->NewNumber(type->Max())); | |
| 735 CHECK(range->Is(type)); | |
| 736 } | |
| 737 } | |
| 738 */ | |
| 739 | |
| 740 // If b1 and b2 are regular numeric bitsets with b1->Is(b2), then | |
| 741 // b1->Min() >= b2->Min() and b1->Max() <= b2->Max(). | |
| 742 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | |
| 743 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | |
| 744 TypeHandle type1 = *it1; | |
| 745 TypeHandle type2 = *it2; | |
| 746 if (this->IsBitset(type1) && type1->Is(type2) && type2->Is(T.Number) && | |
| 747 !type1->Is(T.NaN) && !type2->Is(T.NaN)) { | |
| 748 CHECK(type1->Min() >= type2->Min()); | |
| 749 CHECK(type1->Max() <= type2->Max()); | |
| 750 } | |
| 751 } | |
| 752 } | |
| 753 | |
| 754 // Lub(Range(x,y))->Min() <= x and y <= Lub(Range(x,y))->Max() | |
| 755 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | |
| 756 TypeHandle type = *it; | |
| 757 if (type->IsRange()) { | |
| 758 TypeHandle lub = Rep::BitsetType::New( | |
| 759 Rep::BitsetType::Lub(type), T.region()); | |
| 760 CHECK(lub->Min() <= type->Min() && type->Max() <= lub->Max()); | |
| 761 } | |
| 762 } | |
| 763 } | |
| 764 | |
| 765 void Context() { | |
| 766 // Constructor | |
| 767 for (int i = 0; i < 20; ++i) { | |
| 768 TypeHandle type = T.Random(); | |
| 769 TypeHandle context = T.Context(type); | |
| 770 CHECK(context->Iscontext()); | |
| 771 } | |
| 772 | |
| 773 // Attributes | |
| 774 for (int i = 0; i < 20; ++i) { | |
| 775 TypeHandle type = T.Random(); | |
| 776 TypeHandle context = T.Context(type); | |
| 777 CheckEqual(type, context->AsContext()->Outer()); | |
| 778 } | |
| 779 | |
| 780 // Functionality & Injectivity: Context(T1) = Context(T2) iff T1 = T2 | |
| 781 for (int i = 0; i < 20; ++i) { | |
| 782 for (int j = 0; j < 20; ++j) { | |
| 783 TypeHandle type1 = T.Random(); | |
| 784 TypeHandle type2 = T.Random(); | |
| 785 TypeHandle context1 = T.Context(type1); | |
| 786 TypeHandle context2 = T.Context(type2); | |
| 787 CHECK(Equal(context1, context2) == Equal(type1, type2)); | |
| 788 } | |
| 789 } | |
| 790 | |
| 791 // Subtyping: Context(T1)->Is(Context(T2)) iff T1 = T2 | |
| 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 outer1 = *it1; | |
| 795 TypeHandle outer2 = *it2; | |
| 796 TypeHandle type1 = T.Context(outer1); | |
| 797 TypeHandle type2 = T.Context(outer2); | |
| 798 CHECK(type1->Is(type2) == outer1->Equals(outer2)); | |
| 799 } | |
| 800 } | |
| 620 } | 801 } |
| 621 | 802 |
| 622 void Array() { | 803 void Array() { |
| 623 // Constructor | 804 // Constructor |
| 624 for (int i = 0; i < 20; ++i) { | 805 for (int i = 0; i < 20; ++i) { |
| 625 TypeHandle type = T.Random(); | 806 TypeHandle type = T.Random(); |
| 626 TypeHandle array = T.Array1(type); | 807 TypeHandle array = T.Array1(type); |
| 627 CHECK(array->IsArray()); | 808 CHECK(array->IsArray()); |
| 628 } | 809 } |
| 629 | 810 |
| 630 // Attributes | 811 // Attributes |
| 631 for (int i = 0; i < 20; ++i) { | 812 for (int i = 0; i < 20; ++i) { |
| 632 TypeHandle type = T.Random(); | 813 TypeHandle type = T.Random(); |
| 633 TypeHandle array = T.Array1(type); | 814 TypeHandle array = T.Array1(type); |
| 634 CheckEqual(type, array->AsArray()->Element()); | 815 CheckEqual(type, array->AsArray()->Element()); |
| 635 } | 816 } |
| 636 | 817 |
| 637 // Functionality & Injectivity: Array(T1) = Array(T2) iff T1 = T2 | 818 // Functionality & Injectivity: Array(T1) = Array(T2) iff T1 = T2 |
| 638 for (int i = 0; i < 20; ++i) { | 819 for (int i = 0; i < 20; ++i) { |
| 639 for (int j = 0; j < 20; ++j) { | 820 for (int j = 0; j < 20; ++j) { |
| 640 TypeHandle type1 = T.Random(); | 821 TypeHandle type1 = T.Random(); |
| 641 TypeHandle type2 = T.Random(); | 822 TypeHandle type2 = T.Random(); |
| 642 TypeHandle array1 = T.Array1(type1); | 823 TypeHandle array1 = T.Array1(type1); |
| 643 TypeHandle array2 = T.Array1(type2); | 824 TypeHandle array2 = T.Array1(type2); |
| 644 CHECK(Equal(array1, array2) == Equal(type1, type2)); | 825 CHECK(Equal(array1, array2) == Equal(type1, type2)); |
| 645 } | 826 } |
| 646 } | 827 } |
| 828 | |
| 829 // Subtyping: Array(T1)->Is(Array(T2)) iff T1 = T2 | |
| 830 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | |
| 831 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | |
| 832 TypeHandle element1 = *it1; | |
| 833 TypeHandle element2 = *it2; | |
| 834 TypeHandle type1 = T.Array1(element1); | |
| 835 TypeHandle type2 = T.Array1(element2); | |
| 836 CHECK(type1->Is(type2) == element1->Equals(element2)); | |
| 837 } | |
| 838 } | |
| 647 } | 839 } |
| 648 | 840 |
| 649 void Function() { | 841 void Function() { |
| 650 // Constructors | 842 // Constructors |
| 651 for (int i = 0; i < 20; ++i) { | 843 for (int i = 0; i < 20; ++i) { |
| 652 for (int j = 0; j < 20; ++j) { | 844 for (int j = 0; j < 20; ++j) { |
| 653 for (int k = 0; k < 20; ++k) { | 845 for (int k = 0; k < 20; ++k) { |
| 654 TypeHandle type1 = T.Random(); | 846 TypeHandle type1 = T.Random(); |
| 655 TypeHandle type2 = T.Random(); | 847 TypeHandle type2 = T.Random(); |
| 656 TypeHandle type3 = T.Random(); | 848 TypeHandle type3 = T.Random(); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 706 TypeHandle function22 = T.Function2(type1, type2, type3); | 898 TypeHandle function22 = T.Function2(type1, type2, type3); |
| 707 TypeHandle function23 = T.Function2(type1, type3, type2); | 899 TypeHandle function23 = T.Function2(type1, type3, type2); |
| 708 CHECK(Equal(function01, function02) == Equal(type2, type3)); | 900 CHECK(Equal(function01, function02) == Equal(type2, type3)); |
| 709 CHECK(Equal(function01, function03) == Equal(type1, type3)); | 901 CHECK(Equal(function01, function03) == Equal(type1, type3)); |
| 710 CHECK(Equal(function11, function12) == Equal(type2, type3)); | 902 CHECK(Equal(function11, function12) == Equal(type2, type3)); |
| 711 CHECK(Equal(function21, function22) == Equal(type2, type3)); | 903 CHECK(Equal(function21, function22) == Equal(type2, type3)); |
| 712 CHECK(Equal(function21, function23) == Equal(type2, type3)); | 904 CHECK(Equal(function21, function23) == Equal(type2, type3)); |
| 713 } | 905 } |
| 714 } | 906 } |
| 715 } | 907 } |
| 908 | |
| 909 // Subtyping: | |
| 910 // Function0(S1, T1)->Is(Function0(S2, T2)) iff S1 = S2 and T1 = T2 | |
| 911 for (TypeIterator i = T.types.begin(); i != T.types.end(); ++i) { | |
| 912 for (TypeIterator j = T.types.begin(); j != T.types.end(); ++j) { | |
| 913 TypeHandle result1 = *i; | |
| 914 TypeHandle receiver1 = *j; | |
| 915 TypeHandle type1 = T.Function0(result1, receiver1); | |
| 916 TypeHandle result2 = T.Random(); | |
| 917 TypeHandle receiver2 = T.Random(); | |
| 918 TypeHandle type2 = T.Function0(result2, receiver2); | |
| 919 CHECK(type1->Is(type2) == | |
| 920 (result1->Equals(result2) && receiver1->Equals(receiver2))); | |
| 921 } | |
| 922 } | |
| 716 } | 923 } |
| 717 | 924 |
| 718 void Of() { | 925 void Of() { |
| 719 // Constant(V)->Is(Of(V)) | 926 // Constant(V)->Is(Of(V)) |
| 720 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 927 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
| 721 Handle<i::Object> value = *vt; | 928 Handle<i::Object> value = *vt; |
| 722 TypeHandle const_type = T.Constant(value); | 929 TypeHandle const_type = T.Constant(value); |
| 723 TypeHandle of_type = T.Of(value); | 930 TypeHandle of_type = T.Of(value); |
| 724 CHECK(const_type->Is(of_type)); | 931 CHECK(const_type->Is(of_type)); |
| 725 } | 932 } |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 916 | 1123 |
| 917 // Antisymmetry: T1->Is(T2) and T2->Is(T1) iff T1 = T2 | 1124 // Antisymmetry: T1->Is(T2) and T2->Is(T1) iff T1 = T2 |
| 918 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 1125 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 919 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 1126 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 920 TypeHandle type1 = *it1; | 1127 TypeHandle type1 = *it1; |
| 921 TypeHandle type2 = *it2; | 1128 TypeHandle type2 = *it2; |
| 922 CHECK((type1->Is(type2) && type2->Is(type1)) == Equal(type1, type2)); | 1129 CHECK((type1->Is(type2) && type2->Is(type1)) == Equal(type1, type2)); |
| 923 } | 1130 } |
| 924 } | 1131 } |
| 925 | 1132 |
| 926 // Class(M1)->Is(Class(M2)) iff M1 = M2 | |
| 927 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) { | |
| 928 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) { | |
| 929 Handle<i::Map> map1 = *mt1; | |
| 930 Handle<i::Map> map2 = *mt2; | |
| 931 TypeHandle class_type1 = T.Class(map1); | |
| 932 TypeHandle class_type2 = T.Class(map2); | |
| 933 CHECK(class_type1->Is(class_type2) == (*map1 == *map2)); | |
| 934 } | |
| 935 } | |
| 936 | |
| 937 // Constant(V1)->Is(Constant(V2)) iff V1 = V2 | |
| 938 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) { | |
| 939 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) { | |
| 940 Handle<i::Object> value1 = *vt1; | |
| 941 Handle<i::Object> value2 = *vt2; | |
| 942 TypeHandle const_type1 = T.Constant(value1); | |
| 943 TypeHandle const_type2 = T.Constant(value2); | |
| 944 CHECK(const_type1->Is(const_type2) == (*value1 == *value2)); | |
| 945 } | |
| 946 } | |
| 947 | |
| 948 // Range(min1, max1)->Is(Range(min2, max2)) iff | |
| 949 // min1 >= min2 /\ max1 <= max2 | |
| 950 for (ValueIterator i1 = T.integers.begin(); | |
| 951 i1 != T.integers.end(); ++i1) { | |
| 952 for (ValueIterator j1 = T.integers.begin(); | |
| 953 j1 != T.integers.end(); ++j1) { | |
| 954 for (ValueIterator i2 = T.integers.begin(); | |
| 955 i2 != T.integers.end(); ++i2) { | |
| 956 for (ValueIterator j2 = T.integers.begin(); | |
| 957 j2 != T.integers.end(); ++j2) { | |
| 958 i::Handle<i::Object> min1 = *i1; | |
| 959 i::Handle<i::Object> max1 = *j1; | |
| 960 i::Handle<i::Object> min2 = *i2; | |
| 961 i::Handle<i::Object> max2 = *j2; | |
| 962 if (min1->Number() > max1->Number()) std::swap(min1, max1); | |
| 963 if (min2->Number() > max2->Number()) std::swap(min2, max2); | |
| 964 TypeHandle type1 = T.Range(min1, max1); | |
| 965 TypeHandle type2 = T.Range(min2, max2); | |
| 966 CHECK(type1->Is(type2) == | |
| 967 (min2->Number() <= min1->Number() && | |
| 968 max1->Number() <= max2->Number())); | |
| 969 } | |
| 970 } | |
| 971 } | |
| 972 } | |
| 973 | |
| 974 // Context(T1)->Is(Context(T2)) iff T1 = T2 | |
| 975 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | |
| 976 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | |
| 977 TypeHandle outer1 = *it1; | |
| 978 TypeHandle outer2 = *it2; | |
| 979 TypeHandle type1 = T.Context(outer1); | |
| 980 TypeHandle type2 = T.Context(outer2); | |
| 981 CHECK(type1->Is(type2) == outer1->Equals(outer2)); | |
| 982 } | |
| 983 } | |
| 984 | |
| 985 // Array(T1)->Is(Array(T2)) iff T1 = T2 | |
| 986 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | |
| 987 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | |
| 988 TypeHandle element1 = *it1; | |
| 989 TypeHandle element2 = *it2; | |
| 990 TypeHandle type1 = T.Array1(element1); | |
| 991 TypeHandle type2 = T.Array1(element2); | |
| 992 CHECK(type1->Is(type2) == element1->Equals(element2)); | |
| 993 } | |
| 994 } | |
| 995 | |
| 996 // Function0(S1, T1)->Is(Function0(S2, T2)) iff S1 = S2 and T1 = T2 | |
| 997 for (TypeIterator i = T.types.begin(); i != T.types.end(); ++i) { | |
| 998 for (TypeIterator j = T.types.begin(); j != T.types.end(); ++j) { | |
| 999 TypeHandle result1 = *i; | |
| 1000 TypeHandle receiver1 = *j; | |
| 1001 TypeHandle type1 = T.Function0(result1, receiver1); | |
| 1002 TypeHandle result2 = T.Random(); | |
| 1003 TypeHandle receiver2 = T.Random(); | |
| 1004 TypeHandle type2 = T.Function0(result2, receiver2); | |
| 1005 CHECK(type1->Is(type2) == | |
| 1006 (result1->Equals(result2) && receiver1->Equals(receiver2))); | |
| 1007 } | |
| 1008 } | |
| 1009 | |
| 1010 // (In-)Compatibilities. | 1133 // (In-)Compatibilities. |
| 1011 for (TypeIterator i = T.types.begin(); i != T.types.end(); ++i) { | 1134 for (TypeIterator i = T.types.begin(); i != T.types.end(); ++i) { |
| 1012 for (TypeIterator j = T.types.begin(); j != T.types.end(); ++j) { | 1135 for (TypeIterator j = T.types.begin(); j != T.types.end(); ++j) { |
| 1013 TypeHandle type1 = *i; | 1136 TypeHandle type1 = *i; |
| 1014 TypeHandle type2 = *j; | 1137 TypeHandle type2 = *j; |
| 1015 CHECK(!type1->Is(type2) || this->IsBitset(type2) || | 1138 CHECK(!type1->Is(type2) || this->IsBitset(type2) || |
| 1016 this->IsUnion(type2) || this->IsUnion(type1) || | 1139 this->IsUnion(type2) || this->IsUnion(type1) || |
| 1017 (type1->IsClass() && type2->IsClass()) || | 1140 (type1->IsClass() && type2->IsClass()) || |
| 1018 (type1->IsConstant() && type2->IsConstant()) || | 1141 (type1->IsConstant() && type2->IsConstant()) || |
| 1019 (type1->IsConstant() && type2->IsRange()) || | 1142 (type1->IsConstant() && type2->IsRange()) || |
| (...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1436 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 1559 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1437 TypeHandle type1 = *it1; | 1560 TypeHandle type1 = *it1; |
| 1438 TypeHandle type2 = *it2; | 1561 TypeHandle type2 = *it2; |
| 1439 TypeHandle union12 = T.Union(type1, type2); | 1562 TypeHandle union12 = T.Union(type1, type2); |
| 1440 TypeHandle union21 = T.Union(type2, type1); | 1563 TypeHandle union21 = T.Union(type2, type1); |
| 1441 CheckEqual(union12, union21); | 1564 CheckEqual(union12, union21); |
| 1442 } | 1565 } |
| 1443 } | 1566 } |
| 1444 | 1567 |
| 1445 // Associativity: Union(T1, Union(T2, T3)) = Union(Union(T1, T2), T3) | 1568 // Associativity: Union(T1, Union(T2, T3)) = Union(Union(T1, T2), T3) |
| 1446 // This does NOT hold! | 1569 // This does NOT hold! For example: |
| 1570 // (Unsigned32 \/ Range(0,5)) \/ Range(-5,0) = Unsigned32 \/ Range(-5,0) | |
| 1571 // Unsigned32 \/ (Range(0,5) \/ Range(-5,0)) = Unsigned32 \/ Range(-5,5) | |
| 1447 /* | 1572 /* |
| 1448 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 1573 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1449 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 1574 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1450 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { | 1575 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { |
| 1451 TypeHandle type1 = *it1; | 1576 TypeHandle type1 = *it1; |
| 1452 TypeHandle type2 = *it2; | 1577 TypeHandle type2 = *it2; |
| 1453 TypeHandle type3 = *it3; | 1578 TypeHandle type3 = *it3; |
| 1454 TypeHandle union12 = T.Union(type1, type2); | 1579 TypeHandle union12 = T.Union(type1, type2); |
| 1455 TypeHandle union23 = T.Union(type2, type3); | 1580 TypeHandle union23 = T.Union(type2, type3); |
| 1456 TypeHandle union1_23 = T.Union(type1, union23); | 1581 TypeHandle union1_23 = T.Union(type1, union23); |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 1476 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 1601 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1477 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 1602 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1478 TypeHandle type1 = *it1; | 1603 TypeHandle type1 = *it1; |
| 1479 TypeHandle type2 = *it2; | 1604 TypeHandle type2 = *it2; |
| 1480 TypeHandle union12 = T.Union(type1, type2); | 1605 TypeHandle union12 = T.Union(type1, type2); |
| 1481 if (type1->Is(type2)) CheckEqual(union12, type2); | 1606 if (type1->Is(type2)) CheckEqual(union12, type2); |
| 1482 } | 1607 } |
| 1483 } | 1608 } |
| 1484 | 1609 |
| 1485 // Monotonicity: T1->Is(T2) implies Union(T1, T3)->Is(Union(T2, T3)) | 1610 // Monotonicity: T1->Is(T2) implies Union(T1, T3)->Is(Union(T2, T3)) |
| 1486 // This does NOT hold. | 1611 // This does NOT hold. For example: |
| 1612 // Range(-5,-1) <= Signed32 | |
| 1613 // Range(-5,-1) \/ Range(1,5) = Range(-5,5) </= Signed32 \/ Range(1,5) | |
| 1487 /* | 1614 /* |
| 1488 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 1615 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1489 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 1616 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1490 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { | 1617 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { |
| 1491 TypeHandle type1 = *it1; | 1618 TypeHandle type1 = *it1; |
| 1492 TypeHandle type2 = *it2; | 1619 TypeHandle type2 = *it2; |
| 1493 TypeHandle type3 = *it3; | 1620 TypeHandle type3 = *it3; |
| 1494 TypeHandle union13 = T.Union(type1, type3); | 1621 TypeHandle union13 = T.Union(type1, type3); |
| 1495 TypeHandle union23 = T.Union(type2, type3); | 1622 TypeHandle union23 = T.Union(type2, type3); |
| 1496 CHECK(!type1->Is(type2) || union13->Is(union23)); | 1623 CHECK(!type1->Is(type2) || union13->Is(union23)); |
| 1497 } | 1624 } |
| 1498 } | 1625 } |
| 1499 } | 1626 } |
| 1500 */ | 1627 */ |
| 1501 } | 1628 } |
| 1502 | 1629 |
| 1503 void Union2() { | 1630 void Union2() { |
| 1504 // Monotonicity: T1->Is(T3) and T2->Is(T3) implies Union(T1, T2)->Is(T3) | 1631 // Monotonicity: T1->Is(T3) and T2->Is(T3) implies Union(T1, T2)->Is(T3) |
| 1505 // This does NOT hold. TODO(neis): Could fix this by splitting | 1632 // This does NOT hold. For example: |
| 1506 // OtherNumber into a negative and a positive part. | 1633 // Range(-2^33, -2^33) <= OtherNumber |
| 1634 // Range(2^33, 2^33) <= OtherNumber | |
| 1635 // Range(-2^33, 2^33) </= OtherNumber | |
| 1507 /* | 1636 /* |
| 1508 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 1637 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1509 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 1638 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1510 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { | 1639 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { |
| 1511 TypeHandle type1 = *it1; | 1640 TypeHandle type1 = *it1; |
| 1512 TypeHandle type2 = *it2; | 1641 TypeHandle type2 = *it2; |
| 1513 TypeHandle type3 = *it3; | 1642 TypeHandle type3 = *it3; |
| 1514 TypeHandle union12 = T.Union(type1, type2); | 1643 TypeHandle union12 = T.Union(type1, type2); |
| 1515 CHECK(!(type1->Is(type3) && type2->Is(type3)) || union12->Is(type3)); | 1644 CHECK(!(type1->Is(type3) && type2->Is(type3)) || union12->Is(type3)); |
| 1516 } | 1645 } |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1678 TypeHandle type1 = *it1; | 1807 TypeHandle type1 = *it1; |
| 1679 TypeHandle type2 = *it2; | 1808 TypeHandle type2 = *it2; |
| 1680 TypeHandle intersect12 = T.Intersect(type1, type2); | 1809 TypeHandle intersect12 = T.Intersect(type1, type2); |
| 1681 TypeHandle intersect21 = T.Intersect(type2, type1); | 1810 TypeHandle intersect21 = T.Intersect(type2, type1); |
| 1682 CheckEqual(intersect12, intersect21); | 1811 CheckEqual(intersect12, intersect21); |
| 1683 } | 1812 } |
| 1684 } | 1813 } |
| 1685 | 1814 |
| 1686 // Associativity: | 1815 // Associativity: |
| 1687 // Intersect(T1, Intersect(T2, T3)) = Intersect(Intersect(T1, T2), T3) | 1816 // Intersect(T1, Intersect(T2, T3)) = Intersect(Intersect(T1, T2), T3) |
| 1688 // This does NOT hold. | 1817 // This does NOT hold. For example: |
| 1818 // (Class(..stringy1..) /\ Class(..stringy2..)) /\ Constant(..string..) = | |
| 1819 // None | |
| 1820 // Class(..stringy1..) /\ (Class(..stringy2..) /\ Constant(..string..)) = | |
| 1821 // Constant(..string..) | |
| 1689 /* | 1822 /* |
| 1690 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 1823 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1691 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 1824 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1692 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { | 1825 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { |
| 1693 TypeHandle type1 = *it1; | 1826 TypeHandle type1 = *it1; |
| 1694 TypeHandle type2 = *it2; | 1827 TypeHandle type2 = *it2; |
| 1695 TypeHandle type3 = *it3; | 1828 TypeHandle type3 = *it3; |
| 1696 TypeHandle intersect12 = T.Intersect(type1, type2); | 1829 TypeHandle intersect12 = T.Intersect(type1, type2); |
| 1697 TypeHandle intersect23 = T.Intersect(type2, type3); | 1830 TypeHandle intersect23 = T.Intersect(type2, type3); |
| 1698 TypeHandle intersect1_23 = T.Intersect(type1, intersect23); | 1831 TypeHandle intersect1_23 = T.Intersect(type1, intersect23); |
| 1699 TypeHandle intersect12_3 = T.Intersect(intersect12, type3); | 1832 TypeHandle intersect12_3 = T.Intersect(intersect12, type3); |
| 1700 CheckEqual(intersect1_23, intersect12_3); | 1833 CheckEqual(intersect1_23, intersect12_3); |
| 1701 } | 1834 } |
| 1702 } | 1835 } |
| 1703 } | 1836 } |
| 1704 */ | 1837 */ |
| 1705 | 1838 |
| 1706 // Join: Intersect(T1, T2)->Is(T1) and Intersect(T1, T2)->Is(T2) | 1839 // Join: Intersect(T1, T2)->Is(T1) and Intersect(T1, T2)->Is(T2) |
| 1707 // This does NOT hold. Not even the disjunction. | 1840 // This does NOT hold. For example: |
| 1841 // Class(..stringy..) /\ Constant(..string..) = Constant(..string..) | |
| 1842 // Currently, not even the disjunction holds: | |
| 1843 // Class(Internal/TaggedPtr) /\ (Any/Untagged \/ Context(..)) = | |
| 1844 // Class(Internal/TaggedPtr) \/ Context(..) | |
| 1708 /* | 1845 /* |
| 1709 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 1846 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1710 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 1847 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1711 TypeHandle type1 = *it1; | 1848 TypeHandle type1 = *it1; |
| 1712 TypeHandle type2 = *it2; | 1849 TypeHandle type2 = *it2; |
| 1713 TypeHandle intersect12 = T.Intersect(type1, type2); | 1850 TypeHandle intersect12 = T.Intersect(type1, type2); |
| 1714 CHECK(intersect12->Is(type1)); | 1851 CHECK(intersect12->Is(type1)); |
| 1715 CHECK(intersect12->Is(type2)); | 1852 CHECK(intersect12->Is(type2)); |
| 1716 } | 1853 } |
| 1717 } | 1854 } |
| 1718 */ | 1855 */ |
| 1719 | 1856 |
| 1720 // Lower Boundedness: T1->Is(T2) implies Intersect(T1, T2) = T1 | 1857 // Lower Boundedness: T1->Is(T2) implies Intersect(T1, T2) = T1 |
| 1721 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 1858 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1722 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 1859 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1723 TypeHandle type1 = *it1; | 1860 TypeHandle type1 = *it1; |
| 1724 TypeHandle type2 = *it2; | 1861 TypeHandle type2 = *it2; |
| 1725 TypeHandle intersect12 = T.Intersect(type1, type2); | 1862 TypeHandle intersect12 = T.Intersect(type1, type2); |
| 1726 if (type1->Is(type2)) CheckEqual(intersect12, type1); | 1863 if (type1->Is(type2)) CheckEqual(intersect12, type1); |
| 1727 } | 1864 } |
| 1728 } | 1865 } |
| 1729 | 1866 |
| 1730 // Monotonicity: T1->Is(T2) implies Intersect(T1, T3)->Is(Intersect(T2, T3)) | 1867 // Monotonicity: T1->Is(T2) implies Intersect(T1, T3)->Is(Intersect(T2, T3)) |
| 1731 // This does NOT hold. | 1868 // This does NOT hold. For example: |
| 1869 // Class(OtherObject/TaggedPtr) <= Any/TaggedPtr | |
| 1870 // Class(OtherObject/TaggedPtr) /\ Any/UntaggedInt1 = Class(..) | |
| 1871 // Any/TaggedPtr /\ Any/UntaggedInt1 = None | |
| 1732 /* | 1872 /* |
| 1733 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 1873 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1734 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 1874 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1735 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { | 1875 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { |
| 1736 TypeHandle type1 = *it1; | 1876 TypeHandle type1 = *it1; |
| 1737 TypeHandle type2 = *it2; | 1877 TypeHandle type2 = *it2; |
| 1738 TypeHandle type3 = *it3; | 1878 TypeHandle type3 = *it3; |
| 1739 TypeHandle intersect13 = T.Intersect(type1, type3); | 1879 TypeHandle intersect13 = T.Intersect(type1, type3); |
| 1740 TypeHandle intersect23 = T.Intersect(type2, type3); | 1880 TypeHandle intersect23 = T.Intersect(type2, type3); |
| 1741 CHECK(!type1->Is(type2) || intersect13->Is(intersect23)); | 1881 CHECK(!type1->Is(type2) || intersect13->Is(intersect23)); |
| 1742 } | 1882 } |
| 1743 } | 1883 } |
| 1744 } | 1884 } |
| 1745 */ | 1885 */ |
| 1746 | 1886 |
| 1747 // Monotonicity: T1->Is(T3) or T2->Is(T3) implies Intersect(T1, T2)->Is(T3) | 1887 // Monotonicity: T1->Is(T3) or T2->Is(T3) implies Intersect(T1, T2)->Is(T3) |
| 1748 // This does NOT hold. | 1888 // This does NOT hold. For example: |
| 1889 // Class(..stringy..) <= Class(..stringy..) | |
| 1890 // Class(..stringy..) /\ Constant(..string..) = Constant(..string..) | |
| 1891 // Constant(..string..) </= Class(..stringy..) | |
| 1749 /* | 1892 /* |
| 1750 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 1893 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1751 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 1894 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1752 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { | 1895 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { |
| 1753 TypeHandle type1 = *it1; | 1896 TypeHandle type1 = *it1; |
| 1754 TypeHandle type2 = *it2; | 1897 TypeHandle type2 = *it2; |
| 1755 TypeHandle type3 = *it3; | 1898 TypeHandle type3 = *it3; |
| 1756 TypeHandle intersect12 = T.Intersect(type1, type2); | 1899 TypeHandle intersect12 = T.Intersect(type1, type2); |
| 1757 CHECK(!(type1->Is(type3) || type2->Is(type3)) || | 1900 CHECK(!(type1->Is(type3) || type2->Is(type3)) || |
| 1758 intersect12->Is(type3)); | 1901 intersect12->Is(type3)); |
| 1759 } | 1902 } |
| 1760 } | 1903 } |
| 1761 } | 1904 } |
| 1762 */ | 1905 */ |
| 1763 | 1906 |
| 1764 // Monotonicity: T1->Is(T2) and T1->Is(T3) implies T1->Is(Intersect(T2, T3)) | 1907 // Monotonicity: T1->Is(T2) and T1->Is(T3) implies T1->Is(Intersect(T2, T3)) |
| 1765 // This does NOT hold. | |
| 1766 /* | |
| 1767 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 1908 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1768 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 1909 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1769 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { | 1910 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { |
| 1770 TypeHandle type1 = *it1; | 1911 TypeHandle type1 = *it1; |
| 1771 TypeHandle type2 = *it2; | 1912 TypeHandle type2 = *it2; |
| 1772 TypeHandle type3 = *it3; | 1913 TypeHandle type3 = *it3; |
| 1773 TypeHandle intersect23 = T.Intersect(type2, type3); | 1914 TypeHandle intersect23 = T.Intersect(type2, type3); |
| 1774 CHECK(!(type1->Is(type2) && type1->Is(type3)) || | 1915 CHECK(!(type1->Is(type2) && type1->Is(type3)) || |
| 1775 type1->Is(intersect23)); | 1916 type1->Is(intersect23)); |
| 1776 } | 1917 } |
| 1777 } | 1918 } |
| 1778 } | 1919 } |
| 1779 */ | |
|
neis1
2014/09/24 12:01:01
I'm not sure why I thought this wouldn't hold anym
| |
| 1780 | 1920 |
| 1781 // Bitset-class | 1921 // Bitset-class |
| 1782 CheckEqual(T.Intersect(T.ObjectClass, T.Object), T.ObjectClass); | 1922 CheckEqual(T.Intersect(T.ObjectClass, T.Object), T.ObjectClass); |
| 1783 CheckEqual(T.Intersect(T.ObjectClass, T.Array), T.None); | 1923 CheckEqual(T.Intersect(T.ObjectClass, T.Array), T.None); |
| 1784 CheckEqual(T.Intersect(T.ObjectClass, T.Number), T.None); | 1924 CheckEqual(T.Intersect(T.ObjectClass, T.Number), T.None); |
| 1785 | 1925 |
| 1786 // Bitset-array | 1926 // Bitset-array |
| 1787 CheckEqual(T.Intersect(T.NumberArray, T.Object), T.NumberArray); | 1927 CheckEqual(T.Intersect(T.NumberArray, T.Object), T.NumberArray); |
| 1788 CheckEqual(T.Intersect(T.AnyArray, T.Function), T.None); | 1928 CheckEqual(T.Intersect(T.AnyArray, T.Function), T.None); |
| 1789 | 1929 |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1873 T.Union( | 2013 T.Union( |
| 1874 T.ObjectConstant1, | 2014 T.ObjectConstant1, |
| 1875 T.Union(T.ArrayConstant, T.ObjectConstant2))), | 2015 T.Union(T.ArrayConstant, T.ObjectConstant2))), |
| 1876 T.Union( | 2016 T.Union( |
| 1877 T.ArrayConstant, | 2017 T.ArrayConstant, |
| 1878 T.Union(T.ObjectConstant2, T.ObjectConstant1))); // !!! | 2018 T.Union(T.ObjectConstant2, T.ObjectConstant1))); // !!! |
| 1879 } | 2019 } |
| 1880 | 2020 |
| 1881 void Distributivity() { | 2021 void Distributivity() { |
| 1882 // Union(T1, Intersect(T2, T3)) = Intersect(Union(T1, T2), Union(T1, T3)) | 2022 // Union(T1, Intersect(T2, T3)) = Intersect(Union(T1, T2), Union(T1, T3)) |
| 1883 // This does NOT hold. | 2023 // This does NOT hold. For example: |
| 2024 // Untagged \/ (Untagged /\ Class(../Tagged)) = Untagged \/ Class(../Tagged) | |
| 2025 // (Untagged \/ Untagged) /\ (Untagged \/ Class(../Tagged)) = | |
| 2026 // Untagged /\ (Untagged \/ Class(../Tagged)) = Untagged | |
| 2027 // because Untagged <= Untagged \/ Class(../Tagged) | |
| 1884 /* | 2028 /* |
| 1885 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 2029 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1886 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 2030 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1887 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { | 2031 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { |
| 1888 TypeHandle type1 = *it1; | 2032 TypeHandle type1 = *it1; |
| 1889 TypeHandle type2 = *it2; | 2033 TypeHandle type2 = *it2; |
| 1890 TypeHandle type3 = *it3; | 2034 TypeHandle type3 = *it3; |
| 1891 TypeHandle union12 = T.Union(type1, type2); | 2035 TypeHandle union12 = T.Union(type1, type2); |
| 1892 TypeHandle union13 = T.Union(type1, type3); | 2036 TypeHandle union13 = T.Union(type1, type3); |
| 1893 TypeHandle intersect23 = T.Intersect(type2, type3); | 2037 TypeHandle intersect23 = T.Intersect(type2, type3); |
| 1894 TypeHandle union1_23 = T.Union(type1, intersect23); | 2038 TypeHandle union1_23 = T.Union(type1, intersect23); |
| 1895 TypeHandle intersect12_13 = T.Intersect(union12, union13); | 2039 TypeHandle intersect12_13 = T.Intersect(union12, union13); |
| 1896 CHECK(Equal(union1_23, intersect12_13)); | 2040 CHECK(Equal(union1_23, intersect12_13)); |
| 1897 } | 2041 } |
| 1898 } | 2042 } |
| 1899 } | 2043 } |
| 1900 */ | 2044 */ |
| 1901 | 2045 |
| 1902 // Intersect(T1, Union(T2, T3)) = Union(Intersect(T1, T2), Intersect(T1,T3)) | 2046 // Intersect(T1, Union(T2, T3)) = Union(Intersect(T1, T2), Intersect(T1,T3)) |
| 1903 // This does NOT hold. | 2047 // This does NOT hold. For example: |
| 2048 // Untagged /\ (Untagged \/ Class(../Tagged)) = Untagged | |
| 2049 // (Untagged /\ Untagged) \/ (Untagged /\ Class(../Tagged)) = | |
| 2050 // Untagged \/ Class(../Tagged) | |
| 1904 /* | 2051 /* |
| 1905 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 2052 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1906 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 2053 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1907 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { | 2054 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { |
| 1908 TypeHandle type1 = *it1; | 2055 TypeHandle type1 = *it1; |
| 1909 TypeHandle type2 = *it2; | 2056 TypeHandle type2 = *it2; |
| 1910 TypeHandle type3 = *it3; | 2057 TypeHandle type3 = *it3; |
| 1911 TypeHandle intersect12 = T.Intersect(type1, type2); | 2058 TypeHandle intersect12 = T.Intersect(type1, type2); |
| 1912 TypeHandle intersect13 = T.Intersect(type1, type3); | 2059 TypeHandle intersect13 = T.Intersect(type1, type3); |
| 1913 TypeHandle union23 = T.Union(type2, type3); | 2060 TypeHandle union23 = T.Union(type2, type3); |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2091 } | 2238 } |
| 2092 | 2239 |
| 2093 | 2240 |
| 2094 TEST(Intersect) { | 2241 TEST(Intersect) { |
| 2095 CcTest::InitializeVM(); | 2242 CcTest::InitializeVM(); |
| 2096 ZoneTests().Intersect(); | 2243 ZoneTests().Intersect(); |
| 2097 HeapTests().Intersect(); | 2244 HeapTests().Intersect(); |
| 2098 } | 2245 } |
| 2099 | 2246 |
| 2100 | 2247 |
| 2101 /* | |
| 2102 TEST(Distributivity) { | 2248 TEST(Distributivity) { |
| 2103 CcTest::InitializeVM(); | 2249 CcTest::InitializeVM(); |
| 2104 ZoneTests().Distributivity(); | 2250 ZoneTests().Distributivity(); |
| 2105 HeapTests().Distributivity(); | 2251 HeapTests().Distributivity(); |
| 2106 } | 2252 } |
| 2107 */ | |
| 2108 | 2253 |
| 2109 | 2254 |
| 2110 TEST(Convert) { | 2255 TEST(Convert) { |
| 2111 CcTest::InitializeVM(); | 2256 CcTest::InitializeVM(); |
| 2112 ZoneTests().Convert<HeapType, Handle<HeapType>, Isolate, HeapRep>(); | 2257 ZoneTests().Convert<HeapType, Handle<HeapType>, Isolate, HeapRep>(); |
| 2113 HeapTests().Convert<Type, Type*, Zone, ZoneRep>(); | 2258 HeapTests().Convert<Type, Type*, Zone, ZoneRep>(); |
| 2114 } | 2259 } |
| 2115 | 2260 |
| 2116 | 2261 |
| 2117 TEST(HTypeFromType) { | 2262 TEST(HTypeFromType) { |
| 2118 CcTest::InitializeVM(); | 2263 CcTest::InitializeVM(); |
| 2119 ZoneTests().HTypeFromType(); | 2264 ZoneTests().HTypeFromType(); |
| 2120 HeapTests().HTypeFromType(); | 2265 HeapTests().HTypeFromType(); |
| 2121 } | 2266 } |
| OLD | NEW |