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