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 |