| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| 11 // with the distribution. | 11 // with the distribution. |
| 12 // * Neither the name of Google Inc. nor the names of its | 12 // * Neither the name of Google Inc. nor the names of its |
| 13 // contributors may be used to endorse or promote products derived | 13 // contributors may be used to endorse or promote products derived |
| 14 // from this software without specific prior written permission. | 14 // from this software without specific prior written permission. |
| 15 // | 15 // |
| 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | 27 |
| 28 #include <vector> |
| 29 |
| 28 #include "cctest.h" | 30 #include "cctest.h" |
| 29 #include "types.h" | 31 #include "types.h" |
| 32 #include "utils/random-number-generator.h" |
| 30 | 33 |
| 31 using namespace v8::internal; | 34 using namespace v8::internal; |
| 32 | 35 |
| 36 // Testing auxiliaries (breaking the Type abstraction). |
| 37 struct ZoneRep { |
| 38 typedef ZoneList<void*> Struct; |
| 39 |
| 40 static bool IsStruct(Type* t, int tag) { |
| 41 return !IsBitset(t) |
| 42 && reinterpret_cast<intptr_t>(AsStruct(t)->at(0)) == tag; |
| 43 } |
| 44 static bool IsBitset(Type* t) { return reinterpret_cast<intptr_t>(t) & 1; } |
| 45 static bool IsClass(Type* t) { return IsStruct(t, 0); } |
| 46 static bool IsConstant(Type* t) { return IsStruct(t, 1); } |
| 47 static bool IsUnion(Type* t) { return IsStruct(t, 2); } |
| 48 |
| 49 static Struct* AsStruct(Type* t) { |
| 50 return reinterpret_cast<Struct*>(t); |
| 51 } |
| 52 static int AsBitset(Type* t) { |
| 53 return static_cast<int>(reinterpret_cast<intptr_t>(t) >> 1); |
| 54 } |
| 55 static Map* AsClass(Type* t) { |
| 56 return *static_cast<Map**>(AsStruct(t)->at(2)); |
| 57 } |
| 58 static Object* AsConstant(Type* t) { |
| 59 return *static_cast<Object**>(AsStruct(t)->at(2)); |
| 60 } |
| 61 static Struct* AsUnion(Type* t) { |
| 62 return AsStruct(t); |
| 63 } |
| 64 static int Length(Struct* structured) { return structured->length() - 2; } |
| 65 |
| 66 static Zone* ToRegion(Zone* zone, Isolate* isolate) { return zone; } |
| 67 }; |
| 68 |
| 69 |
| 70 struct HeapRep { |
| 71 static bool IsBitset(Handle<HeapType> t) { return t->IsSmi(); } |
| 72 static bool IsClass(Handle<HeapType> t) { return t->IsMap(); } |
| 73 static bool IsConstant(Handle<HeapType> t) { return t->IsBox(); } |
| 74 static bool IsUnion(Handle<HeapType> t) { return t->IsFixedArray(); } |
| 75 |
| 76 static int AsBitset(Handle<HeapType> t) { return Smi::cast(*t)->value(); } |
| 77 static Map* AsClass(Handle<HeapType> t) { return Map::cast(*t); } |
| 78 static Object* AsConstant(Handle<HeapType> t) { |
| 79 return Box::cast(*t)->value(); |
| 80 } |
| 81 static FixedArray* AsUnion(Handle<HeapType> t) { |
| 82 return FixedArray::cast(*t); |
| 83 } |
| 84 static int Length(FixedArray* structured) { return structured->length(); } |
| 85 |
| 86 static Isolate* ToRegion(Zone* zone, Isolate* isolate) { return isolate; } |
| 87 }; |
| 88 |
| 89 |
| 33 template<class Type, class TypeHandle, class Region> | 90 template<class Type, class TypeHandle, class Region> |
| 34 class Types { | 91 class Types { |
| 35 public: | 92 public: |
| 36 Types(Region* region, Isolate* isolate) : | 93 Types(Region* region, Isolate* isolate) : region_(region) { |
| 37 Representation(Type::Representation(region)), | 94 #define DECLARE_TYPE(name, value) \ |
| 38 Semantic(Type::Semantic(region)), | 95 name = Type::name(region); \ |
| 39 None(Type::None(region)), | 96 types.push_back(name); |
| 40 Any(Type::Any(region)), | 97 BITSET_TYPE_LIST(DECLARE_TYPE) |
| 41 Oddball(Type::Oddball(region)), | 98 #undef DECLARE_TYPE |
| 42 Boolean(Type::Boolean(region)), | 99 |
| 43 Null(Type::Null(region)), | 100 object_map = isolate->factory()->NewMap(JS_OBJECT_TYPE, 3 * kPointerSize); |
| 44 Undefined(Type::Undefined(region)), | 101 array_map = isolate->factory()->NewMap(JS_ARRAY_TYPE, 4 * kPointerSize); |
| 45 Number(Type::Number(region)), | 102 ObjectClass = Type::Class(object_map, region); |
| 46 SignedSmall(Type::SignedSmall(region)), | 103 ArrayClass = Type::Class(array_map, region); |
| 47 Signed32(Type::Signed32(region)), | 104 |
| 48 Float(Type::Float(region)), | 105 maps.push_back(object_map); |
| 49 Name(Type::Name(region)), | 106 maps.push_back(array_map); |
| 50 UniqueName(Type::UniqueName(region)), | 107 for (MapVector::iterator it = maps.begin(); it != maps.end(); ++it) { |
| 51 String(Type::String(region)), | 108 types.push_back(Type::Class(*it, region)); |
| 52 InternalizedString(Type::InternalizedString(region)), | 109 } |
| 53 Symbol(Type::Symbol(region)), | 110 |
| 54 Receiver(Type::Receiver(region)), | |
| 55 Object(Type::Object(region)), | |
| 56 Array(Type::Array(region)), | |
| 57 Function(Type::Function(region)), | |
| 58 Proxy(Type::Proxy(region)), | |
| 59 object_map(isolate->factory()->NewMap(JS_OBJECT_TYPE, 3 * kPointerSize)), | |
| 60 array_map(isolate->factory()->NewMap(JS_ARRAY_TYPE, 4 * kPointerSize)), | |
| 61 region_(region) { | |
| 62 smi = handle(Smi::FromInt(666), isolate); | 111 smi = handle(Smi::FromInt(666), isolate); |
| 63 signed32 = isolate->factory()->NewHeapNumber(0x40000000); | 112 signed32 = isolate->factory()->NewHeapNumber(0x40000000); |
| 64 object1 = isolate->factory()->NewJSObjectFromMap(object_map); | 113 object1 = isolate->factory()->NewJSObjectFromMap(object_map); |
| 65 object2 = isolate->factory()->NewJSObjectFromMap(object_map); | 114 object2 = isolate->factory()->NewJSObjectFromMap(object_map); |
| 66 array = isolate->factory()->NewJSArray(20); | 115 array = isolate->factory()->NewJSArray(20); |
| 67 ObjectClass = Type::Class(object_map, region); | |
| 68 ArrayClass = Type::Class(array_map, region); | |
| 69 SmiConstant = Type::Constant(smi, region); | 116 SmiConstant = Type::Constant(smi, region); |
| 70 Signed32Constant = Type::Constant(signed32, region); | 117 Signed32Constant = Type::Constant(signed32, region); |
| 71 ObjectConstant1 = Type::Constant(object1, region); | 118 ObjectConstant1 = Type::Constant(object1, region); |
| 72 ObjectConstant2 = Type::Constant(object2, region); | 119 ObjectConstant2 = Type::Constant(object2, region); |
| 73 ArrayConstant1 = Type::Constant(array, region); | 120 ArrayConstant = Type::Constant(array, region); |
| 74 ArrayConstant2 = Type::Constant(array, region); | 121 |
| 122 values.push_back(smi); |
| 123 values.push_back(signed32); |
| 124 values.push_back(object1); |
| 125 values.push_back(object2); |
| 126 values.push_back(array); |
| 127 for (ValueVector::iterator it = values.begin(); it != values.end(); ++it) { |
| 128 types.push_back(Type::Constant(*it, region)); |
| 129 } |
| 130 |
| 131 for (int i = 0; i < 50; ++i) { |
| 132 types.push_back(Fuzz()); |
| 133 } |
| 75 } | 134 } |
| 76 | 135 |
| 77 TypeHandle Representation; | |
| 78 TypeHandle Semantic; | |
| 79 TypeHandle None; | |
| 80 TypeHandle Any; | |
| 81 TypeHandle Oddball; | |
| 82 TypeHandle Boolean; | |
| 83 TypeHandle Null; | |
| 84 TypeHandle Undefined; | |
| 85 TypeHandle Number; | |
| 86 TypeHandle SignedSmall; | |
| 87 TypeHandle Signed32; | |
| 88 TypeHandle Float; | |
| 89 TypeHandle Name; | |
| 90 TypeHandle UniqueName; | |
| 91 TypeHandle String; | |
| 92 TypeHandle InternalizedString; | |
| 93 TypeHandle Symbol; | |
| 94 TypeHandle Receiver; | |
| 95 TypeHandle Object; | |
| 96 TypeHandle Array; | |
| 97 TypeHandle Function; | |
| 98 TypeHandle Proxy; | |
| 99 | |
| 100 TypeHandle ObjectClass; | |
| 101 TypeHandle ArrayClass; | |
| 102 | |
| 103 TypeHandle SmiConstant; | |
| 104 TypeHandle Signed32Constant; | |
| 105 TypeHandle ObjectConstant1; | |
| 106 TypeHandle ObjectConstant2; | |
| 107 TypeHandle ArrayConstant1; | |
| 108 TypeHandle ArrayConstant2; | |
| 109 | |
| 110 Handle<i::Map> object_map; | 136 Handle<i::Map> object_map; |
| 111 Handle<i::Map> array_map; | 137 Handle<i::Map> array_map; |
| 112 | 138 |
| 113 Handle<i::Smi> smi; | 139 Handle<i::Smi> smi; |
| 114 Handle<i::HeapNumber> signed32; | 140 Handle<i::HeapNumber> signed32; |
| 115 Handle<i::JSObject> object1; | 141 Handle<i::JSObject> object1; |
| 116 Handle<i::JSObject> object2; | 142 Handle<i::JSObject> object2; |
| 117 Handle<i::JSArray> array; | 143 Handle<i::JSArray> array; |
| 118 | 144 |
| 145 #define DECLARE_TYPE(name, value) TypeHandle name; |
| 146 BITSET_TYPE_LIST(DECLARE_TYPE) |
| 147 #undef DECLARE_TYPE |
| 148 |
| 149 TypeHandle ObjectClass; |
| 150 TypeHandle ArrayClass; |
| 151 |
| 152 TypeHandle SmiConstant; |
| 153 TypeHandle Signed32Constant; |
| 154 TypeHandle ObjectConstant1; |
| 155 TypeHandle ObjectConstant2; |
| 156 TypeHandle ArrayConstant; |
| 157 |
| 158 typedef std::vector<TypeHandle> TypeVector; |
| 159 typedef std::vector<Handle<i::Map> > MapVector; |
| 160 typedef std::vector<Handle<i::Object> > ValueVector; |
| 161 TypeVector types; |
| 162 MapVector maps; |
| 163 ValueVector values; |
| 164 |
| 165 TypeHandle Of(Handle<i::Object> value) { |
| 166 return Type::Of(value, region_); |
| 167 } |
| 168 |
| 169 TypeHandle NowOf(Handle<i::Object> value) { |
| 170 return Type::NowOf(value, region_); |
| 171 } |
| 172 |
| 173 TypeHandle Constant(Handle<i::Object> value) { |
| 174 return Type::Constant(value, region_); |
| 175 } |
| 176 |
| 177 TypeHandle Class(Handle<i::Map> map) { |
| 178 return Type::Class(map, region_); |
| 179 } |
| 180 |
| 119 TypeHandle Union(TypeHandle t1, TypeHandle t2) { | 181 TypeHandle Union(TypeHandle t1, TypeHandle t2) { |
| 120 return Type::Union(t1, t2, region_); | 182 return Type::Union(t1, t2, region_); |
| 121 } | 183 } |
| 122 TypeHandle Intersect(TypeHandle t1, TypeHandle t2) { | 184 TypeHandle Intersect(TypeHandle t1, TypeHandle t2) { |
| 123 return Type::Intersect(t1, t2, region_); | 185 return Type::Intersect(t1, t2, region_); |
| 124 } | 186 } |
| 125 | 187 |
| 126 template<class Type2, class TypeHandle2> | 188 template<class Type2, class TypeHandle2> |
| 127 TypeHandle Convert(TypeHandle2 t) { | 189 TypeHandle Convert(TypeHandle2 t) { |
| 128 return Type::template Convert<Type2>(t, region_); | 190 return Type::template Convert<Type2>(t, region_); |
| 129 } | 191 } |
| 130 | 192 |
| 193 TypeHandle Random() { |
| 194 return types[rng_.NextInt(static_cast<int>(types.size()))]; |
| 195 } |
| 196 |
| 131 TypeHandle Fuzz(int depth = 5) { | 197 TypeHandle Fuzz(int depth = 5) { |
| 132 switch (rand() % (depth == 0 ? 3 : 20)) { | 198 switch (rng_.NextInt(depth == 0 ? 3 : 20)) { |
| 133 case 0: { // bitset | 199 case 0: { // bitset |
| 134 int n = 0 | 200 int n = 0 |
| 135 #define COUNT_BITSET_TYPES(type, value) + 1 | 201 #define COUNT_BITSET_TYPES(type, value) + 1 |
| 136 BITSET_TYPE_LIST(COUNT_BITSET_TYPES) | 202 BITSET_TYPE_LIST(COUNT_BITSET_TYPES) |
| 137 #undef COUNT_BITSET_TYPES | 203 #undef COUNT_BITSET_TYPES |
| 138 ; | 204 ; |
| 139 int i = rand() % n; | 205 int i = rng_.NextInt(n); |
| 140 #define PICK_BITSET_TYPE(type, value) \ | 206 #define PICK_BITSET_TYPE(type, value) \ |
| 141 if (i-- == 0) return Type::type(region_); | 207 if (i-- == 0) return Type::type(region_); |
| 142 BITSET_TYPE_LIST(PICK_BITSET_TYPE) | 208 BITSET_TYPE_LIST(PICK_BITSET_TYPE) |
| 143 #undef PICK_BITSET_TYPE | 209 #undef PICK_BITSET_TYPE |
| 144 UNREACHABLE(); | 210 UNREACHABLE(); |
| 145 } | 211 } |
| 146 case 1: // class | 212 case 1: { // class |
| 147 switch (rand() % 2) { | 213 int i = rng_.NextInt(static_cast<int>(maps.size())); |
| 148 case 0: return ObjectClass; | 214 return Type::Class(maps[i], region_); |
| 149 case 1: return ArrayClass; | 215 } |
| 150 } | 216 case 2: { // constant |
| 151 UNREACHABLE(); | 217 int i = rng_.NextInt(static_cast<int>(values.size())); |
| 152 case 2: // constant | 218 return Type::Constant(values[i], region_); |
| 153 switch (rand() % 6) { | 219 } |
| 154 case 0: return SmiConstant; | |
| 155 case 1: return Signed32Constant; | |
| 156 case 2: return ObjectConstant1; | |
| 157 case 3: return ObjectConstant2; | |
| 158 case 4: return ArrayConstant1; | |
| 159 case 5: return ArrayConstant2; | |
| 160 } | |
| 161 UNREACHABLE(); | |
| 162 default: { // union | 220 default: { // union |
| 163 int n = rand() % 10; | 221 int n = rng_.NextInt(10); |
| 164 TypeHandle type = None; | 222 TypeHandle type = None; |
| 165 for (int i = 0; i < n; ++i) { | 223 for (int i = 0; i < n; ++i) { |
| 166 type = Type::Union(type, Fuzz(depth - 1), region_); | 224 TypeHandle operand = Fuzz(depth - 1); |
| 225 type = Type::Union(type, operand, region_); |
| 167 } | 226 } |
| 168 return type; | 227 return type; |
| 169 } | 228 } |
| 170 } | 229 } |
| 171 UNREACHABLE(); | 230 UNREACHABLE(); |
| 172 } | 231 } |
| 173 | 232 |
| 174 private: | 233 private: |
| 175 Region* region_; | 234 Region* region_; |
| 176 }; | 235 RandomNumberGenerator rng_; |
| 177 | |
| 178 | |
| 179 // Testing auxiliaries (breaking the Type abstraction). | |
| 180 struct ZoneRep { | |
| 181 static bool IsTagged(Type* t, int tag) { | |
| 182 return !IsBitset(t) | |
| 183 && reinterpret_cast<intptr_t>(AsTagged(t)->at(0)) == tag; | |
| 184 } | |
| 185 static bool IsBitset(Type* t) { return reinterpret_cast<intptr_t>(t) & 1; } | |
| 186 static bool IsClass(Type* t) { return IsTagged(t, 0); } | |
| 187 static bool IsConstant(Type* t) { return IsTagged(t, 1); } | |
| 188 static bool IsUnion(Type* t) { return IsTagged(t, 2); } | |
| 189 | |
| 190 static ZoneList<void*>* AsTagged(Type* t) { | |
| 191 return reinterpret_cast<ZoneList<void*>*>(t); | |
| 192 } | |
| 193 static int AsBitset(Type* t) { | |
| 194 return static_cast<int>(reinterpret_cast<intptr_t>(t) >> 1); | |
| 195 } | |
| 196 static Map* AsClass(Type* t) { | |
| 197 return *reinterpret_cast<Map**>(AsTagged(t)->at(2)); | |
| 198 } | |
| 199 static Object* AsConstant(Type* t) { | |
| 200 return *reinterpret_cast<Object**>(AsTagged(t)->at(2)); | |
| 201 } | |
| 202 static ZoneList<Type*>* AsUnion(Type* t) { | |
| 203 return reinterpret_cast<ZoneList<Type*>*>(AsTagged(t)); | |
| 204 } | |
| 205 | |
| 206 static Zone* ToRegion(Zone* zone, Isolate* isolate) { return zone; } | |
| 207 }; | |
| 208 | |
| 209 | |
| 210 struct HeapRep { | |
| 211 static bool IsBitset(Handle<HeapType> t) { return t->IsSmi(); } | |
| 212 static bool IsClass(Handle<HeapType> t) { return t->IsMap(); } | |
| 213 static bool IsConstant(Handle<HeapType> t) { return t->IsBox(); } | |
| 214 static bool IsUnion(Handle<HeapType> t) { return t->IsFixedArray(); } | |
| 215 | |
| 216 static int AsBitset(Handle<HeapType> t) { return Smi::cast(*t)->value(); } | |
| 217 static Map* AsClass(Handle<HeapType> t) { return Map::cast(*t); } | |
| 218 static Object* AsConstant(Handle<HeapType> t) { | |
| 219 return Box::cast(*t)->value(); | |
| 220 } | |
| 221 static FixedArray* AsUnion(Handle<HeapType> t) { | |
| 222 return FixedArray::cast(*t); | |
| 223 } | |
| 224 | |
| 225 static Isolate* ToRegion(Zone* zone, Isolate* isolate) { return isolate; } | |
| 226 }; | 236 }; |
| 227 | 237 |
| 228 | 238 |
| 229 template<class Type, class TypeHandle, class Region, class Rep> | 239 template<class Type, class TypeHandle, class Region, class Rep> |
| 230 struct Tests : Rep { | 240 struct Tests : Rep { |
| 241 typedef Types<Type, TypeHandle, Region> TypesInstance; |
| 242 typedef typename TypesInstance::TypeVector::iterator TypeIterator; |
| 243 typedef typename TypesInstance::MapVector::iterator MapIterator; |
| 244 typedef typename TypesInstance::ValueVector::iterator ValueIterator; |
| 245 |
| 231 Isolate* isolate; | 246 Isolate* isolate; |
| 232 HandleScope scope; | 247 HandleScope scope; |
| 233 Zone zone; | 248 Zone zone; |
| 234 Types<Type, TypeHandle, Region> T; | 249 TypesInstance T; |
| 235 | 250 |
| 236 Tests() : | 251 Tests() : |
| 237 isolate(CcTest::i_isolate()), | 252 isolate(CcTest::i_isolate()), |
| 238 scope(isolate), | 253 scope(isolate), |
| 239 zone(isolate), | 254 zone(isolate), |
| 240 T(Rep::ToRegion(&zone, isolate), isolate) { | 255 T(Rep::ToRegion(&zone, isolate), isolate) { |
| 241 } | 256 } |
| 242 | 257 |
| 258 bool Equal(TypeHandle type1, TypeHandle type2) { |
| 259 return |
| 260 type1->Is(type2) && type2->Is(type1) && |
| 261 Rep::IsBitset(type1) == Rep::IsBitset(type2) && |
| 262 Rep::IsClass(type1) == Rep::IsClass(type2) && |
| 263 Rep::IsConstant(type1) == Rep::IsConstant(type2) && |
| 264 Rep::IsUnion(type1) == Rep::IsUnion(type2) && |
| 265 type1->NumClasses() == type2->NumClasses() && |
| 266 type1->NumConstants() == type2->NumConstants() && |
| 267 (!Rep::IsBitset(type1) || |
| 268 Rep::AsBitset(type1) == Rep::AsBitset(type2)) && |
| 269 (!Rep::IsClass(type1) || |
| 270 Rep::AsClass(type1) == Rep::AsClass(type2)) && |
| 271 (!Rep::IsConstant(type1) || |
| 272 Rep::AsConstant(type1) == Rep::AsConstant(type2)) && |
| 273 (!Rep::IsUnion(type1) || |
| 274 Rep::Length(Rep::AsUnion(type1)) == Rep::Length(Rep::AsUnion(type2))); |
| 275 } |
| 276 |
| 243 void CheckEqual(TypeHandle type1, TypeHandle type2) { | 277 void CheckEqual(TypeHandle type1, TypeHandle type2) { |
| 244 CHECK_EQ(Rep::IsBitset(type1), Rep::IsBitset(type2)); | 278 CHECK(Equal(type1, type2)); |
| 245 CHECK_EQ(Rep::IsClass(type1), Rep::IsClass(type2)); | |
| 246 CHECK_EQ(Rep::IsConstant(type1), Rep::IsConstant(type2)); | |
| 247 CHECK_EQ(Rep::IsUnion(type1), Rep::IsUnion(type2)); | |
| 248 CHECK_EQ(type1->NumClasses(), type2->NumClasses()); | |
| 249 CHECK_EQ(type1->NumConstants(), type2->NumConstants()); | |
| 250 if (Rep::IsBitset(type1)) { | |
| 251 CHECK_EQ(Rep::AsBitset(type1), Rep::AsBitset(type2)); | |
| 252 } else if (Rep::IsClass(type1)) { | |
| 253 CHECK_EQ(Rep::AsClass(type1), Rep::AsClass(type2)); | |
| 254 } else if (Rep::IsConstant(type1)) { | |
| 255 CHECK_EQ(Rep::AsConstant(type1), Rep::AsConstant(type2)); | |
| 256 } else if (Rep::IsUnion(type1)) { | |
| 257 CHECK_EQ(Rep::AsUnion(type1)->length(), Rep::AsUnion(type2)->length()); | |
| 258 } | |
| 259 CHECK(type1->Is(type2)); | |
| 260 CHECK(type2->Is(type1)); | |
| 261 } | 279 } |
| 262 | 280 |
| 263 void CheckSub(TypeHandle type1, TypeHandle type2) { | 281 void CheckSub(TypeHandle type1, TypeHandle type2) { |
| 264 CHECK(type1->Is(type2)); | 282 CHECK(type1->Is(type2)); |
| 265 CHECK(!type2->Is(type1)); | 283 CHECK(!type2->Is(type1)); |
| 266 if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) { | 284 if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) { |
| 267 CHECK_NE(Rep::AsBitset(type1), Rep::AsBitset(type2)); | 285 CHECK_NE(Rep::AsBitset(type1), Rep::AsBitset(type2)); |
| 268 } | 286 } |
| 269 } | 287 } |
| 270 | 288 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 290 CHECK(!type2->Is(type1)); | 308 CHECK(!type2->Is(type1)); |
| 291 CHECK(!type1->Maybe(type2)); | 309 CHECK(!type1->Maybe(type2)); |
| 292 CHECK(!type2->Maybe(type1)); | 310 CHECK(!type2->Maybe(type1)); |
| 293 if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) { | 311 if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) { |
| 294 CHECK_EQ(0, | 312 CHECK_EQ(0, |
| 295 Rep::AsBitset(type1) & Rep::AsBitset(type2) & Rep::AsBitset(mask)); | 313 Rep::AsBitset(type1) & Rep::AsBitset(type2) & Rep::AsBitset(mask)); |
| 296 } | 314 } |
| 297 } | 315 } |
| 298 | 316 |
| 299 void Bitset() { | 317 void Bitset() { |
| 318 // None and Any are bitsets. |
| 300 CHECK(this->IsBitset(T.None)); | 319 CHECK(this->IsBitset(T.None)); |
| 301 CHECK(this->IsBitset(T.Any)); | 320 CHECK(this->IsBitset(T.Any)); |
| 302 CHECK(this->IsBitset(T.String)); | |
| 303 CHECK(this->IsBitset(T.Object)); | |
| 304 | |
| 305 CHECK(this->IsBitset(T.Union(T.String, T.Number))); | |
| 306 CHECK(this->IsBitset(T.Union(T.String, T.Receiver))); | |
| 307 | 321 |
| 308 CHECK_EQ(0, this->AsBitset(T.None)); | 322 CHECK_EQ(0, this->AsBitset(T.None)); |
| 309 CHECK_EQ( | 323 CHECK_EQ(-1, this->AsBitset(T.Any)); |
| 310 this->AsBitset(T.Number) | this->AsBitset(T.String), | 324 |
| 311 this->AsBitset(T.Union(T.String, T.Number))); | 325 // Union(T1, T2) is bitset for bitsets T1,T2 |
| 312 CHECK_EQ( | 326 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 313 this->AsBitset(T.Receiver), | 327 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 314 this->AsBitset(T.Union(T.Receiver, T.Object))); | 328 TypeHandle type1 = *it1; |
| 329 TypeHandle type2 = *it2; |
| 330 TypeHandle union12 = T.Union(type1, type2); |
| 331 CHECK(!(this->IsBitset(type1) && this->IsBitset(type2)) || |
| 332 this->IsBitset(union12)); |
| 333 } |
| 334 } |
| 335 |
| 336 // Intersect(T1, T2) is bitset for bitsets T1,T2 |
| 337 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 338 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 339 TypeHandle type1 = *it1; |
| 340 TypeHandle type2 = *it2; |
| 341 TypeHandle intersect12 = T.Intersect(type1, type2); |
| 342 CHECK(!(this->IsBitset(type1) && this->IsBitset(type2)) || |
| 343 this->IsBitset(intersect12)); |
| 344 } |
| 345 } |
| 346 |
| 347 // Union(T1, T2) is bitset if T2 is bitset and T1->Is(T2) |
| 348 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 349 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 350 TypeHandle type1 = *it1; |
| 351 TypeHandle type2 = *it2; |
| 352 TypeHandle union12 = T.Union(type1, type2); |
| 353 CHECK(!(this->IsBitset(type2) && type1->Is(type2)) || |
| 354 this->IsBitset(union12)); |
| 355 } |
| 356 } |
| 357 |
| 358 // Union(T1, T2) is bitwise disjunction for bitsets T1,T2 |
| 359 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 360 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 361 TypeHandle type1 = *it1; |
| 362 TypeHandle type2 = *it2; |
| 363 TypeHandle union12 = T.Union(type1, type2); |
| 364 if (this->IsBitset(type1) && this->IsBitset(type2)) { |
| 365 CHECK_EQ( |
| 366 this->AsBitset(type1) | this->AsBitset(type2), |
| 367 this->AsBitset(union12)); |
| 368 } |
| 369 } |
| 370 } |
| 371 |
| 372 // Intersect(T1, T2) is bitwise conjunction for bitsets T1,T2 |
| 373 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 374 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 375 TypeHandle type1 = *it1; |
| 376 TypeHandle type2 = *it2; |
| 377 TypeHandle intersect12 = T.Intersect(type1, type2); |
| 378 if (this->IsBitset(type1) && this->IsBitset(type2)) { |
| 379 CHECK_EQ( |
| 380 this->AsBitset(type1) & this->AsBitset(type2), |
| 381 this->AsBitset(intersect12)); |
| 382 } |
| 383 } |
| 384 } |
| 315 } | 385 } |
| 316 | 386 |
| 317 void Class() { | 387 void Class() { |
| 318 CHECK(this->IsClass(T.ObjectClass)); | 388 // Constructor |
| 319 CHECK(this->IsClass(T.ArrayClass)); | 389 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { |
| 320 | 390 Handle<i::Map> map = *mt; |
| 321 CHECK(*T.object_map == this->AsClass(T.ObjectClass)); | 391 TypeHandle type = T.Class(map); |
| 322 CHECK(*T.array_map == this->AsClass(T.ArrayClass)); | 392 CHECK(this->IsClass(type)); |
| 393 } |
| 394 |
| 395 // Map attribute |
| 396 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { |
| 397 Handle<i::Map> map = *mt; |
| 398 TypeHandle type = T.Class(map); |
| 399 CHECK(*map == *type->AsClass()); |
| 400 } |
| 401 |
| 402 // Functionality & Injectivity: Class(M1) = Class(M2) iff M1 = M2 |
| 403 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) { |
| 404 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) { |
| 405 Handle<i::Map> map1 = *mt1; |
| 406 Handle<i::Map> map2 = *mt2; |
| 407 TypeHandle type1 = T.Class(map1); |
| 408 TypeHandle type2 = T.Class(map2); |
| 409 CHECK(Equal(type1, type2) == (*map1 == *map2)); |
| 410 } |
| 411 } |
| 323 } | 412 } |
| 324 | 413 |
| 325 void Constant() { | 414 void Constant() { |
| 326 CHECK(this->IsConstant(T.SmiConstant)); | 415 // Constructor |
| 327 CHECK(this->IsConstant(T.ObjectConstant1)); | 416 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
| 328 CHECK(this->IsConstant(T.ObjectConstant2)); | 417 Handle<i::Object> value = *vt; |
| 329 CHECK(this->IsConstant(T.ArrayConstant1)); | 418 TypeHandle type = T.Constant(value); |
| 330 CHECK(this->IsConstant(T.ArrayConstant2)); | 419 CHECK(this->IsConstant(type)); |
| 331 | 420 } |
| 332 CHECK(*T.smi == this->AsConstant(T.SmiConstant)); | 421 |
| 333 CHECK(*T.object1 == this->AsConstant(T.ObjectConstant1)); | 422 // Value attribute |
| 334 CHECK(*T.object2 == this->AsConstant(T.ObjectConstant2)); | 423 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
| 335 CHECK(*T.object1 != this->AsConstant(T.ObjectConstant2)); | 424 Handle<i::Object> value = *vt; |
| 336 CHECK(*T.array == this->AsConstant(T.ArrayConstant1)); | 425 TypeHandle type = T.Constant(value); |
| 337 CHECK(*T.array == this->AsConstant(T.ArrayConstant2)); | 426 CHECK(*value == *type->AsConstant()); |
| 427 } |
| 428 |
| 429 // Functionality & Injectivity: Constant(V1) = Constant(V2) iff V1 = V2 |
| 430 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) { |
| 431 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) { |
| 432 Handle<i::Object> value1 = *vt1; |
| 433 Handle<i::Object> value2 = *vt2; |
| 434 TypeHandle type1 = T.Constant(value1); |
| 435 TypeHandle type2 = T.Constant(value2); |
| 436 CHECK(Equal(type1, type2) == (*value1 == *value2)); |
| 437 } |
| 438 } |
| 439 } |
| 440 |
| 441 void Of() { |
| 442 // Constant(V)->Is(Of(V)) |
| 443 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
| 444 Handle<i::Object> value = *vt; |
| 445 TypeHandle const_type = T.Constant(value); |
| 446 TypeHandle of_type = T.Of(value); |
| 447 CHECK(const_type->Is(of_type)); |
| 448 } |
| 449 |
| 450 // Constant(V)->Is(T) iff Of(V)->Is(T) or T->Maybe(Constant(V)) |
| 451 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
| 452 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 453 Handle<i::Object> value = *vt; |
| 454 TypeHandle type = *it; |
| 455 TypeHandle const_type = T.Constant(value); |
| 456 TypeHandle of_type = T.Of(value); |
| 457 CHECK(const_type->Is(type) == |
| 458 (of_type->Is(type) || type->Maybe(const_type))); |
| 459 } |
| 460 } |
| 338 } | 461 } |
| 339 | 462 |
| 340 void Is() { | 463 void Is() { |
| 341 // Reflexivity | 464 // Least Element (Bottom): None->Is(T) |
| 342 CHECK(T.None->Is(T.None)); | 465 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 343 CHECK(T.Any->Is(T.Any)); | 466 TypeHandle type = *it; |
| 344 CHECK(T.Object->Is(T.Object)); | 467 CHECK(T.None->Is(type)); |
| 345 | 468 } |
| 346 CHECK(T.ObjectClass->Is(T.ObjectClass)); | 469 |
| 347 CHECK(T.ObjectConstant1->Is(T.ObjectConstant1)); | 470 // Greatest Element (Top): T->Is(Any) |
| 348 CHECK(T.ArrayConstant1->Is(T.ArrayConstant2)); | 471 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 349 | 472 TypeHandle type = *it; |
| 350 // Symmetry and Transitivity | 473 CHECK(type->Is(T.Any)); |
| 351 CheckSub(T.None, T.Number); | 474 } |
| 352 CheckSub(T.None, T.Any); | 475 |
| 353 | 476 // Bottom Uniqueness: T->Is(None) implies T = None |
| 354 CheckSub(T.Oddball, T.Any); | 477 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 355 CheckSub(T.Boolean, T.Oddball); | 478 TypeHandle type = *it; |
| 356 CheckSub(T.Null, T.Oddball); | 479 if (type->Is(T.None)) CheckEqual(type, T.None); |
| 357 CheckSub(T.Undefined, T.Oddball); | 480 } |
| 481 |
| 482 // Top Uniqueness: Any->Is(T) implies T = Any |
| 483 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 484 TypeHandle type = *it; |
| 485 if (T.Any->Is(type)) CheckEqual(type, T.Any); |
| 486 } |
| 487 |
| 488 // Reflexivity: T->Is(T) |
| 489 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 490 TypeHandle type = *it; |
| 491 CHECK(type->Is(type)); |
| 492 } |
| 493 |
| 494 // Transitivity: T1->Is(T2) and T2->Is(T3) implies T1->Is(T3) |
| 495 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 496 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 497 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { |
| 498 TypeHandle type1 = *it1; |
| 499 TypeHandle type2 = *it2; |
| 500 TypeHandle type3 = *it3; |
| 501 CHECK(!(type1->Is(type2) && type2->Is(type3)) || type1->Is(type3)); |
| 502 } |
| 503 } |
| 504 } |
| 505 |
| 506 // Antisymmetry: T1->Is(T2) and T2->Is(T1) iff T1 = T2 |
| 507 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 508 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 509 TypeHandle type1 = *it1; |
| 510 TypeHandle type2 = *it2; |
| 511 CHECK((type1->Is(type2) && type2->Is(type1)) == Equal(type1, type2)); |
| 512 } |
| 513 } |
| 514 |
| 515 // Constant(V1)->Is(Constant(V2)) iff V1 = V2 |
| 516 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) { |
| 517 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) { |
| 518 Handle<i::Object> value1 = *vt1; |
| 519 Handle<i::Object> value2 = *vt2; |
| 520 TypeHandle const_type1 = T.Constant(value1); |
| 521 TypeHandle const_type2 = T.Constant(value2); |
| 522 CHECK(const_type1->Is(const_type2) == (*value1 == *value2)); |
| 523 } |
| 524 } |
| 525 |
| 526 // Class(M1)->Is(Class(M2)) iff M1 = M2 |
| 527 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) { |
| 528 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) { |
| 529 Handle<i::Map> map1 = *mt1; |
| 530 Handle<i::Map> map2 = *mt2; |
| 531 TypeHandle class_type1 = T.Class(map1); |
| 532 TypeHandle class_type2 = T.Class(map2); |
| 533 CHECK(class_type1->Is(class_type2) == (*map1 == *map2)); |
| 534 } |
| 535 } |
| 536 |
| 537 // Constant(V)->Is(Class(M)) never |
| 538 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { |
| 539 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
| 540 Handle<i::Map> map = *mt; |
| 541 Handle<i::Object> value = *vt; |
| 542 TypeHandle constant_type = T.Constant(value); |
| 543 TypeHandle class_type = T.Class(map); |
| 544 CHECK(!constant_type->Is(class_type)); |
| 545 } |
| 546 } |
| 547 |
| 548 // Class(M)->Is(Constant(V)) never |
| 549 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { |
| 550 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
| 551 Handle<i::Map> map = *mt; |
| 552 Handle<i::Object> value = *vt; |
| 553 TypeHandle constant_type = T.Constant(value); |
| 554 TypeHandle class_type = T.Class(map); |
| 555 CHECK(!class_type->Is(constant_type)); |
| 556 } |
| 557 } |
| 558 |
| 559 // Basic types |
| 358 CheckUnordered(T.Boolean, T.Null); | 560 CheckUnordered(T.Boolean, T.Null); |
| 359 CheckUnordered(T.Undefined, T.Null); | 561 CheckUnordered(T.Undefined, T.Null); |
| 360 CheckUnordered(T.Boolean, T.Undefined); | 562 CheckUnordered(T.Boolean, T.Undefined); |
| 361 | 563 |
| 362 CheckSub(T.Number, T.Any); | |
| 363 CheckSub(T.SignedSmall, T.Number); | 564 CheckSub(T.SignedSmall, T.Number); |
| 364 CheckSub(T.Signed32, T.Number); | 565 CheckSub(T.Signed32, T.Number); |
| 365 CheckSub(T.Float, T.Number); | 566 CheckSub(T.Float, T.Number); |
| 366 CheckSub(T.SignedSmall, T.Signed32); | 567 CheckSub(T.SignedSmall, T.Signed32); |
| 367 CheckUnordered(T.SignedSmall, T.Float); | 568 CheckUnordered(T.SignedSmall, T.Float); |
| 368 CheckUnordered(T.Signed32, T.Float); | 569 CheckUnordered(T.Signed32, T.Float); |
| 369 | 570 |
| 370 CheckSub(T.Name, T.Any); | |
| 371 CheckSub(T.UniqueName, T.Any); | |
| 372 CheckSub(T.UniqueName, T.Name); | 571 CheckSub(T.UniqueName, T.Name); |
| 373 CheckSub(T.String, T.Name); | 572 CheckSub(T.String, T.Name); |
| 374 CheckSub(T.InternalizedString, T.String); | 573 CheckSub(T.InternalizedString, T.String); |
| 375 CheckSub(T.InternalizedString, T.UniqueName); | 574 CheckSub(T.InternalizedString, T.UniqueName); |
| 376 CheckSub(T.InternalizedString, T.Name); | 575 CheckSub(T.InternalizedString, T.Name); |
| 377 CheckSub(T.Symbol, T.UniqueName); | 576 CheckSub(T.Symbol, T.UniqueName); |
| 378 CheckSub(T.Symbol, T.Name); | 577 CheckSub(T.Symbol, T.Name); |
| 379 CheckUnordered(T.String, T.UniqueName); | 578 CheckUnordered(T.String, T.UniqueName); |
| 380 CheckUnordered(T.String, T.Symbol); | 579 CheckUnordered(T.String, T.Symbol); |
| 381 CheckUnordered(T.InternalizedString, T.Symbol); | 580 CheckUnordered(T.InternalizedString, T.Symbol); |
| 382 | 581 |
| 383 CheckSub(T.Receiver, T.Any); | |
| 384 CheckSub(T.Object, T.Any); | |
| 385 CheckSub(T.Object, T.Receiver); | 582 CheckSub(T.Object, T.Receiver); |
| 386 CheckSub(T.Array, T.Object); | 583 CheckSub(T.Array, T.Object); |
| 387 CheckSub(T.Function, T.Object); | 584 CheckSub(T.Function, T.Object); |
| 388 CheckSub(T.Proxy, T.Receiver); | 585 CheckSub(T.Proxy, T.Receiver); |
| 389 CheckUnordered(T.Object, T.Proxy); | 586 CheckUnordered(T.Object, T.Proxy); |
| 390 CheckUnordered(T.Array, T.Function); | 587 CheckUnordered(T.Array, T.Function); |
| 391 | 588 |
| 392 // Structured subtyping | 589 // Structural types |
| 393 CheckSub(T.None, T.ObjectClass); | |
| 394 CheckSub(T.None, T.ObjectConstant1); | |
| 395 CheckSub(T.ObjectClass, T.Any); | |
| 396 CheckSub(T.ObjectConstant1, T.Any); | |
| 397 | |
| 398 CheckSub(T.ObjectClass, T.Object); | 590 CheckSub(T.ObjectClass, T.Object); |
| 399 CheckSub(T.ArrayClass, T.Object); | 591 CheckSub(T.ArrayClass, T.Object); |
| 592 CheckSub(T.ArrayClass, T.Array); |
| 400 CheckUnordered(T.ObjectClass, T.ArrayClass); | 593 CheckUnordered(T.ObjectClass, T.ArrayClass); |
| 401 | 594 |
| 402 CheckSub(T.SmiConstant, T.SignedSmall); | 595 CheckSub(T.SmiConstant, T.SignedSmall); |
| 403 CheckSub(T.SmiConstant, T.Signed32); | 596 CheckSub(T.SmiConstant, T.Signed32); |
| 404 CheckSub(T.SmiConstant, T.Number); | 597 CheckSub(T.SmiConstant, T.Number); |
| 405 CheckSub(T.ObjectConstant1, T.Object); | 598 CheckSub(T.ObjectConstant1, T.Object); |
| 406 CheckSub(T.ObjectConstant2, T.Object); | 599 CheckSub(T.ObjectConstant2, T.Object); |
| 407 CheckSub(T.ArrayConstant1, T.Object); | 600 CheckSub(T.ArrayConstant, T.Object); |
| 408 CheckSub(T.ArrayConstant1, T.Array); | 601 CheckSub(T.ArrayConstant, T.Array); |
| 409 CheckUnordered(T.ObjectConstant1, T.ObjectConstant2); | 602 CheckUnordered(T.ObjectConstant1, T.ObjectConstant2); |
| 410 CheckUnordered(T.ObjectConstant1, T.ArrayConstant1); | 603 CheckUnordered(T.ObjectConstant1, T.ArrayConstant); |
| 411 | 604 |
| 412 CheckUnordered(T.ObjectConstant1, T.ObjectClass); | 605 CheckUnordered(T.ObjectConstant1, T.ObjectClass); |
| 413 CheckUnordered(T.ObjectConstant2, T.ObjectClass); | 606 CheckUnordered(T.ObjectConstant2, T.ObjectClass); |
| 414 CheckUnordered(T.ObjectConstant1, T.ArrayClass); | 607 CheckUnordered(T.ObjectConstant1, T.ArrayClass); |
| 415 CheckUnordered(T.ObjectConstant2, T.ArrayClass); | 608 CheckUnordered(T.ObjectConstant2, T.ArrayClass); |
| 416 CheckUnordered(T.ArrayConstant1, T.ObjectClass); | 609 CheckUnordered(T.ArrayConstant, T.ObjectClass); |
| 417 } | 610 } |
| 418 | 611 |
| 419 void Maybe() { | 612 void Maybe() { |
| 420 CheckOverlap(T.Any, T.Any, T.Semantic); | 613 // T->Maybe(None) never |
| 421 CheckOverlap(T.Object, T.Object, T.Semantic); | 614 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 615 TypeHandle type = *it; |
| 616 CHECK(!type->Maybe(T.None)); |
| 617 } |
| 422 | 618 |
| 423 CheckOverlap(T.Oddball, T.Any, T.Semantic); | 619 // Symmetry: T1->Maybe(T2) iff T2->Maybe(T1) |
| 424 CheckOverlap(T.Boolean, T.Oddball, T.Semantic); | 620 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 425 CheckOverlap(T.Null, T.Oddball, T.Semantic); | 621 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 426 CheckOverlap(T.Undefined, T.Oddball, T.Semantic); | 622 TypeHandle type1 = *it1; |
| 623 TypeHandle type2 = *it2; |
| 624 CHECK(type1->Maybe(type2) == type2->Maybe(type1)); |
| 625 } |
| 626 } |
| 627 |
| 628 // Constant(V1)->Maybe(Constant(V2)) iff V1 = V2 |
| 629 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) { |
| 630 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) { |
| 631 Handle<i::Object> value1 = *vt1; |
| 632 Handle<i::Object> value2 = *vt2; |
| 633 TypeHandle const_type1 = T.Constant(value1); |
| 634 TypeHandle const_type2 = T.Constant(value2); |
| 635 CHECK(const_type1->Maybe(const_type2) == (*value1 == *value2)); |
| 636 } |
| 637 } |
| 638 |
| 639 // Class(M1)->Maybe(Class(M2)) iff M1 = M2 |
| 640 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) { |
| 641 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) { |
| 642 Handle<i::Map> map1 = *mt1; |
| 643 Handle<i::Map> map2 = *mt2; |
| 644 TypeHandle class_type1 = T.Class(map1); |
| 645 TypeHandle class_type2 = T.Class(map2); |
| 646 CHECK(class_type1->Maybe(class_type2) == (*map1 == *map2)); |
| 647 } |
| 648 } |
| 649 |
| 650 // Constant(V)->Maybe(Class(M)) never |
| 651 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { |
| 652 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
| 653 Handle<i::Map> map = *mt; |
| 654 Handle<i::Object> value = *vt; |
| 655 TypeHandle const_type = T.Constant(value); |
| 656 TypeHandle class_type = T.Class(map); |
| 657 CHECK(!const_type->Maybe(class_type)); |
| 658 } |
| 659 } |
| 660 |
| 661 // Class(M)->Maybe(Constant(V)) never |
| 662 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { |
| 663 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
| 664 Handle<i::Map> map = *mt; |
| 665 Handle<i::Object> value = *vt; |
| 666 TypeHandle const_type = T.Constant(value); |
| 667 TypeHandle class_type = T.Class(map); |
| 668 CHECK(!class_type->Maybe(const_type)); |
| 669 } |
| 670 } |
| 671 |
| 672 // Basic types |
| 427 CheckDisjoint(T.Boolean, T.Null, T.Semantic); | 673 CheckDisjoint(T.Boolean, T.Null, T.Semantic); |
| 428 CheckDisjoint(T.Undefined, T.Null, T.Semantic); | 674 CheckDisjoint(T.Undefined, T.Null, T.Semantic); |
| 429 CheckDisjoint(T.Boolean, T.Undefined, T.Semantic); | 675 CheckDisjoint(T.Boolean, T.Undefined, T.Semantic); |
| 430 | 676 |
| 431 CheckOverlap(T.Number, T.Any, T.Semantic); | |
| 432 CheckOverlap(T.SignedSmall, T.Number, T.Semantic); | 677 CheckOverlap(T.SignedSmall, T.Number, T.Semantic); |
| 433 CheckOverlap(T.Float, T.Number, T.Semantic); | 678 CheckOverlap(T.Float, T.Number, T.Semantic); |
| 434 CheckDisjoint(T.Signed32, T.Float, T.Semantic); | 679 CheckDisjoint(T.Signed32, T.Float, T.Semantic); |
| 435 | 680 |
| 436 CheckOverlap(T.Name, T.Any, T.Semantic); | |
| 437 CheckOverlap(T.UniqueName, T.Any, T.Semantic); | |
| 438 CheckOverlap(T.UniqueName, T.Name, T.Semantic); | 681 CheckOverlap(T.UniqueName, T.Name, T.Semantic); |
| 439 CheckOverlap(T.String, T.Name, T.Semantic); | 682 CheckOverlap(T.String, T.Name, T.Semantic); |
| 440 CheckOverlap(T.InternalizedString, T.String, T.Semantic); | 683 CheckOverlap(T.InternalizedString, T.String, T.Semantic); |
| 441 CheckOverlap(T.InternalizedString, T.UniqueName, T.Semantic); | 684 CheckOverlap(T.InternalizedString, T.UniqueName, T.Semantic); |
| 442 CheckOverlap(T.InternalizedString, T.Name, T.Semantic); | 685 CheckOverlap(T.InternalizedString, T.Name, T.Semantic); |
| 443 CheckOverlap(T.Symbol, T.UniqueName, T.Semantic); | 686 CheckOverlap(T.Symbol, T.UniqueName, T.Semantic); |
| 444 CheckOverlap(T.Symbol, T.Name, T.Semantic); | 687 CheckOverlap(T.Symbol, T.Name, T.Semantic); |
| 445 CheckOverlap(T.String, T.UniqueName, T.Semantic); | 688 CheckOverlap(T.String, T.UniqueName, T.Semantic); |
| 446 CheckDisjoint(T.String, T.Symbol, T.Semantic); | 689 CheckDisjoint(T.String, T.Symbol, T.Semantic); |
| 447 CheckDisjoint(T.InternalizedString, T.Symbol, T.Semantic); | 690 CheckDisjoint(T.InternalizedString, T.Symbol, T.Semantic); |
| 448 | 691 |
| 449 CheckOverlap(T.Receiver, T.Any, T.Semantic); | |
| 450 CheckOverlap(T.Object, T.Any, T.Semantic); | |
| 451 CheckOverlap(T.Object, T.Receiver, T.Semantic); | 692 CheckOverlap(T.Object, T.Receiver, T.Semantic); |
| 452 CheckOverlap(T.Array, T.Object, T.Semantic); | 693 CheckOverlap(T.Array, T.Object, T.Semantic); |
| 453 CheckOverlap(T.Function, T.Object, T.Semantic); | 694 CheckOverlap(T.Function, T.Object, T.Semantic); |
| 454 CheckOverlap(T.Proxy, T.Receiver, T.Semantic); | 695 CheckOverlap(T.Proxy, T.Receiver, T.Semantic); |
| 455 CheckDisjoint(T.Object, T.Proxy, T.Semantic); | 696 CheckDisjoint(T.Object, T.Proxy, T.Semantic); |
| 456 CheckDisjoint(T.Array, T.Function, T.Semantic); | 697 CheckDisjoint(T.Array, T.Function, T.Semantic); |
| 457 | 698 |
| 458 CheckOverlap(T.ObjectClass, T.Any, T.Semantic); | 699 // Structural types |
| 459 CheckOverlap(T.ObjectConstant1, T.Any, T.Semantic); | |
| 460 | |
| 461 CheckOverlap(T.ObjectClass, T.Object, T.Semantic); | 700 CheckOverlap(T.ObjectClass, T.Object, T.Semantic); |
| 462 CheckOverlap(T.ArrayClass, T.Object, T.Semantic); | 701 CheckOverlap(T.ArrayClass, T.Object, T.Semantic); |
| 463 CheckOverlap(T.ObjectClass, T.ObjectClass, T.Semantic); | 702 CheckOverlap(T.ObjectClass, T.ObjectClass, T.Semantic); |
| 464 CheckOverlap(T.ArrayClass, T.ArrayClass, T.Semantic); | 703 CheckOverlap(T.ArrayClass, T.ArrayClass, T.Semantic); |
| 465 CheckDisjoint(T.ObjectClass, T.ArrayClass, T.Semantic); | 704 CheckDisjoint(T.ObjectClass, T.ArrayClass, T.Semantic); |
| 466 | 705 |
| 467 CheckOverlap(T.SmiConstant, T.SignedSmall, T.Semantic); | 706 CheckOverlap(T.SmiConstant, T.SignedSmall, T.Semantic); |
| 468 CheckOverlap(T.SmiConstant, T.Signed32, T.Semantic); | 707 CheckOverlap(T.SmiConstant, T.Signed32, T.Semantic); |
| 469 CheckOverlap(T.SmiConstant, T.Number, T.Semantic); | 708 CheckOverlap(T.SmiConstant, T.Number, T.Semantic); |
| 470 CheckDisjoint(T.SmiConstant, T.Float, T.Semantic); | 709 CheckDisjoint(T.SmiConstant, T.Float, T.Semantic); |
| 471 CheckOverlap(T.ObjectConstant1, T.Object, T.Semantic); | 710 CheckOverlap(T.ObjectConstant1, T.Object, T.Semantic); |
| 472 CheckOverlap(T.ObjectConstant2, T.Object, T.Semantic); | 711 CheckOverlap(T.ObjectConstant2, T.Object, T.Semantic); |
| 473 CheckOverlap(T.ArrayConstant1, T.Object, T.Semantic); | 712 CheckOverlap(T.ArrayConstant, T.Object, T.Semantic); |
| 474 CheckOverlap(T.ArrayConstant1, T.Array, T.Semantic); | 713 CheckOverlap(T.ArrayConstant, T.Array, T.Semantic); |
| 475 CheckOverlap(T.ArrayConstant1, T.ArrayConstant2, T.Semantic); | |
| 476 CheckOverlap(T.ObjectConstant1, T.ObjectConstant1, T.Semantic); | 714 CheckOverlap(T.ObjectConstant1, T.ObjectConstant1, T.Semantic); |
| 477 CheckDisjoint(T.ObjectConstant1, T.ObjectConstant2, T.Semantic); | 715 CheckDisjoint(T.ObjectConstant1, T.ObjectConstant2, T.Semantic); |
| 478 CheckDisjoint(T.ObjectConstant1, T.ArrayConstant1, T.Semantic); | 716 CheckDisjoint(T.ObjectConstant1, T.ArrayConstant, T.Semantic); |
| 479 | 717 |
| 480 CheckDisjoint(T.ObjectConstant1, T.ObjectClass, T.Semantic); | 718 CheckDisjoint(T.ObjectConstant1, T.ObjectClass, T.Semantic); |
| 481 CheckDisjoint(T.ObjectConstant2, T.ObjectClass, T.Semantic); | 719 CheckDisjoint(T.ObjectConstant2, T.ObjectClass, T.Semantic); |
| 482 CheckDisjoint(T.ObjectConstant1, T.ArrayClass, T.Semantic); | 720 CheckDisjoint(T.ObjectConstant1, T.ArrayClass, T.Semantic); |
| 483 CheckDisjoint(T.ObjectConstant2, T.ArrayClass, T.Semantic); | 721 CheckDisjoint(T.ObjectConstant2, T.ArrayClass, T.Semantic); |
| 484 CheckDisjoint(T.ArrayConstant1, T.ObjectClass, T.Semantic); | 722 CheckDisjoint(T.ArrayConstant, T.ObjectClass, T.Semantic); |
| 485 } | 723 } |
| 486 | 724 |
| 487 void Union() { | 725 void Union1() { |
| 488 // Bitset-bitset | 726 // Identity: Union(T, None) = T |
| 489 CHECK(this->IsBitset(T.Union(T.Object, T.Number))); | 727 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 490 CHECK(this->IsBitset(T.Union(T.Object, T.Object))); | 728 TypeHandle type = *it; |
| 491 CHECK(this->IsBitset(T.Union(T.Any, T.None))); | 729 TypeHandle union_type = T.Union(type, T.None); |
| 730 CheckEqual(union_type, type); |
| 731 } |
| 492 | 732 |
| 493 CheckEqual(T.Union(T.None, T.Number), T.Number); | 733 // Domination: Union(T, Any) = Any |
| 494 CheckEqual(T.Union(T.Object, T.Proxy), T.Receiver); | 734 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 495 CheckEqual(T.Union(T.Number, T.String), T.Union(T.String, T.Number)); | 735 TypeHandle type = *it; |
| 496 CheckSub(T.Union(T.Number, T.String), T.Any); | 736 TypeHandle union_type = T.Union(type, T.Any); |
| 737 CheckEqual(union_type, T.Any); |
| 738 } |
| 739 |
| 740 // Idempotence: Union(T, T) = T |
| 741 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 742 TypeHandle type = *it; |
| 743 TypeHandle union_type = T.Union(type, type); |
| 744 CheckEqual(union_type, type); |
| 745 } |
| 746 |
| 747 // Commutativity: Union(T1, T2) = Union(T2, T1) |
| 748 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 749 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 750 TypeHandle type1 = *it1; |
| 751 TypeHandle type2 = *it2; |
| 752 TypeHandle union12 = T.Union(type1, type2); |
| 753 TypeHandle union21 = T.Union(type2, type1); |
| 754 CheckEqual(union12, union21); |
| 755 } |
| 756 } |
| 757 |
| 758 // Associativity: Union(T1, Union(T2, T3)) = Union(Union(T1, T2), T3) |
| 759 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 760 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 761 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { |
| 762 TypeHandle type1 = *it1; |
| 763 TypeHandle type2 = *it2; |
| 764 TypeHandle type3 = *it3; |
| 765 TypeHandle union12 = T.Union(type1, type2); |
| 766 TypeHandle union23 = T.Union(type2, type3); |
| 767 TypeHandle union1_23 = T.Union(type1, union23); |
| 768 TypeHandle union12_3 = T.Union(union12, type3); |
| 769 CheckEqual(union1_23, union12_3); |
| 770 } |
| 771 } |
| 772 } |
| 773 |
| 774 // Meet: T1->Is(Union(T1, T2)) and T2->Is(Union(T1, T2)) |
| 775 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 776 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 777 TypeHandle type1 = *it1; |
| 778 TypeHandle type2 = *it2; |
| 779 TypeHandle union12 = T.Union(type1, type2); |
| 780 CHECK(type1->Is(union12)); |
| 781 CHECK(type2->Is(union12)); |
| 782 } |
| 783 } |
| 784 |
| 785 // Upper Boundedness: T1->Is(T2) implies Union(T1, T2) = T2 |
| 786 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 787 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 788 TypeHandle type1 = *it1; |
| 789 TypeHandle type2 = *it2; |
| 790 TypeHandle union12 = T.Union(type1, type2); |
| 791 if (type1->Is(type2)) CheckEqual(union12, type2); |
| 792 } |
| 793 } |
| 794 } |
| 795 |
| 796 void Union2() { |
| 797 // Monotonicity: T1->Is(T2) implies Union(T1, T3)->Is(Union(T2, T3)) |
| 798 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 799 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 800 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { |
| 801 TypeHandle type1 = *it1; |
| 802 TypeHandle type2 = *it2; |
| 803 TypeHandle type3 = *it3; |
| 804 TypeHandle union13 = T.Union(type1, type3); |
| 805 TypeHandle union23 = T.Union(type2, type3); |
| 806 CHECK(!type1->Is(type2) || union13->Is(union23)); |
| 807 } |
| 808 } |
| 809 } |
| 810 |
| 811 // Monotonicity: T1->Is(T3) and T2->Is(T3) implies Union(T1, T2)->Is(T3) |
| 812 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 813 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 814 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { |
| 815 TypeHandle type1 = *it1; |
| 816 TypeHandle type2 = *it2; |
| 817 TypeHandle type3 = *it3; |
| 818 TypeHandle union12 = T.Union(type1, type2); |
| 819 CHECK(!(type1->Is(type3) && type2->Is(type3)) || union12->Is(type3)); |
| 820 } |
| 821 } |
| 822 } |
| 823 |
| 824 // Monotonicity: T1->Is(T2) or T1->Is(T3) implies T1->Is(Union(T2, T3)) |
| 825 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 826 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 827 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { |
| 828 TypeHandle type1 = *it1; |
| 829 TypeHandle type2 = *it2; |
| 830 TypeHandle type3 = *it3; |
| 831 TypeHandle union23 = T.Union(type2, type3); |
| 832 CHECK(!(type1->Is(type2) || type1->Is(type3)) || type1->Is(union23)); |
| 833 } |
| 834 } |
| 835 } |
| 497 | 836 |
| 498 // Class-class | 837 // Class-class |
| 499 CHECK(this->IsClass(T.Union(T.ObjectClass, T.ObjectClass))); | |
| 500 CHECK(this->IsUnion(T.Union(T.ObjectClass, T.ArrayClass))); | |
| 501 | |
| 502 CheckEqual(T.Union(T.ObjectClass, T.ObjectClass), T.ObjectClass); | |
| 503 CheckSub(T.None, T.Union(T.ObjectClass, T.ArrayClass)); | |
| 504 CheckSub(T.Union(T.ObjectClass, T.ArrayClass), T.Any); | |
| 505 CheckSub(T.ObjectClass, T.Union(T.ObjectClass, T.ArrayClass)); | |
| 506 CheckSub(T.ArrayClass, T.Union(T.ObjectClass, T.ArrayClass)); | |
| 507 CheckSub(T.Union(T.ObjectClass, T.ArrayClass), T.Object); | 838 CheckSub(T.Union(T.ObjectClass, T.ArrayClass), T.Object); |
| 508 CheckUnordered(T.Union(T.ObjectClass, T.ArrayClass), T.Array); | 839 CheckUnordered(T.Union(T.ObjectClass, T.ArrayClass), T.Array); |
| 509 CheckOverlap(T.Union(T.ObjectClass, T.ArrayClass), T.Array, T.Semantic); | 840 CheckOverlap(T.Union(T.ObjectClass, T.ArrayClass), T.Array, T.Semantic); |
| 510 CheckDisjoint(T.Union(T.ObjectClass, T.ArrayClass), T.Number, T.Semantic); | 841 CheckDisjoint(T.Union(T.ObjectClass, T.ArrayClass), T.Number, T.Semantic); |
| 511 | 842 |
| 512 // Constant-constant | 843 // Constant-constant |
| 513 CHECK(this->IsConstant(T.Union(T.ObjectConstant1, T.ObjectConstant1))); | |
| 514 CHECK(this->IsConstant(T.Union(T.ArrayConstant1, T.ArrayConstant1))); | |
| 515 CHECK(this->IsUnion(T.Union(T.ObjectConstant1, T.ObjectConstant2))); | |
| 516 | |
| 517 CheckEqual( | |
| 518 T.Union(T.ObjectConstant1, T.ObjectConstant1), | |
| 519 T.ObjectConstant1); | |
| 520 CheckEqual(T.Union(T.ArrayConstant1, T.ArrayConstant1), T.ArrayConstant1); | |
| 521 CheckEqual(T.Union(T.ArrayConstant1, T.ArrayConstant1), T.ArrayConstant2); | |
| 522 CheckSub(T.None, T.Union(T.ObjectConstant1, T.ObjectConstant2)); | |
| 523 CheckSub(T.Union(T.ObjectConstant1, T.ObjectConstant2), T.Any); | |
| 524 CheckSub(T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)); | |
| 525 CheckSub(T.ObjectConstant2, T.Union(T.ObjectConstant1, T.ObjectConstant2)); | |
| 526 CheckSub(T.ArrayConstant2, T.Union(T.ArrayConstant1, T.ObjectConstant2)); | |
| 527 CheckSub(T.Union(T.ObjectConstant1, T.ObjectConstant2), T.Object); | 844 CheckSub(T.Union(T.ObjectConstant1, T.ObjectConstant2), T.Object); |
| 845 CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayConstant), T.Array); |
| 528 CheckUnordered( | 846 CheckUnordered( |
| 529 T.Union(T.ObjectConstant1, T.ObjectConstant2), T.ObjectClass); | 847 T.Union(T.ObjectConstant1, T.ObjectConstant2), T.ObjectClass); |
| 530 CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayConstant1), T.Array); | |
| 531 CheckOverlap( | 848 CheckOverlap( |
| 532 T.Union(T.ObjectConstant1, T.ArrayConstant1), T.Array, T.Semantic); | 849 T.Union(T.ObjectConstant1, T.ArrayConstant), T.Array, T.Semantic); |
| 533 CheckOverlap( | |
| 534 T.Union(T.ObjectConstant1, T.ArrayConstant1), T.ArrayConstant2, | |
| 535 T.Semantic); | |
| 536 CheckDisjoint( | 850 CheckDisjoint( |
| 537 T.Union(T.ObjectConstant1, T.ArrayConstant1), T.Number, T.Semantic); | 851 T.Union(T.ObjectConstant1, T.ArrayConstant), T.Number, T.Semantic); |
| 538 CheckDisjoint( | 852 CheckDisjoint( |
| 539 T.Union(T.ObjectConstant1, T.ArrayConstant1), T.ObjectClass, | 853 T.Union(T.ObjectConstant1, T.ArrayConstant), T.ObjectClass, T.Semantic); |
| 540 T.Semantic); | |
| 541 | 854 |
| 542 // Bitset-class | 855 // Bitset-class |
| 543 CHECK(this->IsBitset(T.Union(T.ObjectClass, T.Object))); | |
| 544 CHECK(this->IsUnion(T.Union(T.ObjectClass, T.Number))); | |
| 545 | |
| 546 CheckEqual(T.Union(T.ObjectClass, T.Object), T.Object); | |
| 547 CheckSub(T.None, T.Union(T.ObjectClass, T.Number)); | |
| 548 CheckSub(T.Union(T.ObjectClass, T.Number), T.Any); | |
| 549 CheckSub( | 856 CheckSub( |
| 550 T.Union(T.ObjectClass, T.SignedSmall), T.Union(T.Object, T.Number)); | 857 T.Union(T.ObjectClass, T.SignedSmall), T.Union(T.Object, T.Number)); |
| 551 CheckSub(T.Union(T.ObjectClass, T.Array), T.Object); | 858 CheckSub(T.Union(T.ObjectClass, T.Array), T.Object); |
| 552 CheckUnordered(T.Union(T.ObjectClass, T.String), T.Array); | 859 CheckUnordered(T.Union(T.ObjectClass, T.String), T.Array); |
| 553 CheckOverlap(T.Union(T.ObjectClass, T.String), T.Object, T.Semantic); | 860 CheckOverlap(T.Union(T.ObjectClass, T.String), T.Object, T.Semantic); |
| 554 CheckDisjoint(T.Union(T.ObjectClass, T.String), T.Number, T.Semantic); | 861 CheckDisjoint(T.Union(T.ObjectClass, T.String), T.Number, T.Semantic); |
| 555 | 862 |
| 556 // Bitset-constant | 863 // Bitset-constant |
| 557 CHECK(this->IsBitset(T.Union(T.SmiConstant, T.Number))); | |
| 558 CHECK(this->IsBitset(T.Union(T.ObjectConstant1, T.Object))); | |
| 559 CHECK(this->IsUnion(T.Union(T.ObjectConstant2, T.Number))); | |
| 560 | |
| 561 CheckEqual(T.Union(T.SmiConstant, T.Number), T.Number); | |
| 562 CheckEqual(T.Union(T.ObjectConstant1, T.Object), T.Object); | |
| 563 CheckSub(T.None, T.Union(T.ObjectConstant1, T.Number)); | |
| 564 CheckSub(T.Union(T.ObjectConstant1, T.Number), T.Any); | |
| 565 CheckSub( | 864 CheckSub( |
| 566 T.Union(T.ObjectConstant1, T.Signed32), T.Union(T.Object, T.Number)); | 865 T.Union(T.ObjectConstant1, T.Signed32), T.Union(T.Object, T.Number)); |
| 567 CheckSub(T.Union(T.ObjectConstant1, T.Array), T.Object); | 866 CheckSub(T.Union(T.ObjectConstant1, T.Array), T.Object); |
| 568 CheckUnordered(T.Union(T.ObjectConstant1, T.String), T.Array); | 867 CheckUnordered(T.Union(T.ObjectConstant1, T.String), T.Array); |
| 569 CheckOverlap(T.Union(T.ObjectConstant1, T.String), T.Object, T.Semantic); | 868 CheckOverlap(T.Union(T.ObjectConstant1, T.String), T.Object, T.Semantic); |
| 570 CheckDisjoint(T.Union(T.ObjectConstant1, T.String), T.Number, T.Semantic); | 869 CheckDisjoint(T.Union(T.ObjectConstant1, T.String), T.Number, T.Semantic); |
| 571 CheckEqual(T.Union(T.Signed32, T.Signed32Constant), T.Signed32); | |
| 572 | 870 |
| 573 // Class-constant | 871 // Class-constant |
| 574 CHECK(this->IsUnion(T.Union(T.ObjectConstant1, T.ObjectClass))); | |
| 575 CHECK(this->IsUnion(T.Union(T.ArrayClass, T.ObjectConstant2))); | |
| 576 | |
| 577 CheckSub(T.None, T.Union(T.ObjectConstant1, T.ArrayClass)); | |
| 578 CheckSub(T.Union(T.ObjectConstant1, T.ArrayClass), T.Any); | |
| 579 CheckSub(T.Union(T.ObjectConstant1, T.ArrayClass), T.Object); | 872 CheckSub(T.Union(T.ObjectConstant1, T.ArrayClass), T.Object); |
| 580 CheckSub(T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ArrayClass)); | |
| 581 CheckSub(T.ArrayClass, T.Union(T.ObjectConstant1, T.ArrayClass)); | |
| 582 CheckUnordered(T.ObjectClass, T.Union(T.ObjectConstant1, T.ArrayClass)); | 873 CheckUnordered(T.ObjectClass, T.Union(T.ObjectConstant1, T.ArrayClass)); |
| 583 CheckSub( | 874 CheckSub( |
| 584 T.Union(T.ObjectConstant1, T.ArrayClass), T.Union(T.Array, T.Object)); | 875 T.Union(T.ObjectConstant1, T.ArrayClass), T.Union(T.Array, T.Object)); |
| 585 CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayClass), T.ArrayConstant1); | 876 CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayClass), T.ArrayConstant); |
| 586 CheckDisjoint( | 877 CheckDisjoint( |
| 587 T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectConstant2, | 878 T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectConstant2, |
| 588 T.Semantic); | 879 T.Semantic); |
| 589 CheckDisjoint( | 880 CheckDisjoint( |
| 590 T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectClass, T.Semantic); | 881 T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectClass, T.Semantic); |
| 591 | 882 |
| 592 // Bitset-union | 883 // Bitset-union |
| 593 CHECK(this->IsBitset( | |
| 594 T.Union(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)))); | |
| 595 CHECK(this->IsUnion( | |
| 596 T.Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.Number))); | |
| 597 | |
| 598 CheckEqual( | |
| 599 T.Union(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)), | |
| 600 T.Object); | |
| 601 CheckEqual( | |
| 602 T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number), | |
| 603 T.Union(T.ObjectConstant1, T.Union(T.Number, T.ArrayClass))); | |
| 604 CheckSub( | 884 CheckSub( |
| 605 T.Float, | 885 T.Float, |
| 606 T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number)); | 886 T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number)); |
| 607 CheckSub( | 887 CheckSub( |
| 608 T.ObjectConstant1, | |
| 609 T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Float)); | |
| 610 CheckSub( | |
| 611 T.None, | |
| 612 T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Float)); | |
| 613 CheckSub( | |
| 614 T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Float), | |
| 615 T.Any); | |
| 616 CheckSub( | |
| 617 T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Float), | 888 T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Float), |
| 618 T.Union(T.ObjectConstant1, T.Union(T.Number, T.ArrayClass))); | 889 T.Union(T.ObjectConstant1, T.Union(T.Number, T.ArrayClass))); |
| 619 | 890 |
| 620 // Class-union | 891 // Class-union |
| 621 CHECK(this->IsUnion( | |
| 622 T.Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass))); | |
| 623 CHECK(this->IsUnion( | |
| 624 T.Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ObjectClass))); | |
| 625 | |
| 626 CheckEqual( | |
| 627 T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)), | |
| 628 T.Union(T.ObjectClass, T.ObjectConstant1)); | |
| 629 CheckSub( | |
| 630 T.None, | |
| 631 T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass))); | |
| 632 CheckSub( | |
| 633 T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)), | |
| 634 T.Any); | |
| 635 CheckSub( | 892 CheckSub( |
| 636 T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)), | 893 T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)), |
| 637 T.Object); | 894 T.Object); |
| 638 CheckEqual( | 895 CheckEqual( |
| 639 T.Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass), | 896 T.Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass), |
| 640 T.Union(T.ArrayClass, T.ObjectConstant2)); | 897 T.Union(T.ArrayClass, T.ObjectConstant2)); |
| 641 | 898 |
| 642 // Constant-union | 899 // Constant-union |
| 643 CHECK(this->IsUnion(T.Union( | |
| 644 T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)))); | |
| 645 CHECK(this->IsUnion(T.Union( | |
| 646 T.Union(T.ArrayConstant1, T.ObjectClass), T.ObjectConstant1))); | |
| 647 CHECK(this->IsUnion(T.Union( | |
| 648 T.Union(T.ArrayConstant1, T.ObjectConstant2), T.ObjectConstant1))); | |
| 649 | |
| 650 CheckEqual( | 900 CheckEqual( |
| 651 T.Union( | 901 T.Union( |
| 652 T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)), | 902 T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)), |
| 653 T.Union(T.ObjectConstant2, T.ObjectConstant1)); | 903 T.Union(T.ObjectConstant2, T.ObjectConstant1)); |
| 654 CheckEqual( | 904 CheckEqual( |
| 655 T.Union( | 905 T.Union( |
| 656 T.Union(T.ArrayConstant1, T.ObjectConstant2), T.ObjectConstant1), | 906 T.Union(T.ArrayConstant, T.ObjectConstant2), T.ObjectConstant1), |
| 657 T.Union( | 907 T.Union( |
| 658 T.ObjectConstant2, T.Union(T.ArrayConstant1, T.ObjectConstant1))); | 908 T.ObjectConstant2, T.Union(T.ArrayConstant, T.ObjectConstant1))); |
| 659 | 909 |
| 660 // Union-union | 910 // Union-union |
| 661 CHECK(this->IsBitset(T.Union( | |
| 662 T.Union(T.Number, T.ArrayClass), | |
| 663 T.Union(T.Signed32, T.Array)))); | |
| 664 CHECK(this->IsUnion(T.Union( | |
| 665 T.Union(T.Number, T.ArrayClass), | |
| 666 T.Union(T.ObjectClass, T.ArrayClass)))); | |
| 667 | |
| 668 CheckEqual( | 911 CheckEqual( |
| 669 T.Union( | 912 T.Union( |
| 670 T.Union(T.ObjectConstant2, T.ObjectConstant1), | 913 T.Union(T.ObjectConstant2, T.ObjectConstant1), |
| 671 T.Union(T.ObjectConstant1, T.ObjectConstant2)), | 914 T.Union(T.ObjectConstant1, T.ObjectConstant2)), |
| 672 T.Union(T.ObjectConstant2, T.ObjectConstant1)); | 915 T.Union(T.ObjectConstant2, T.ObjectConstant1)); |
| 673 CheckEqual( | 916 CheckEqual( |
| 674 T.Union( | 917 T.Union( |
| 675 T.Union(T.ObjectConstant2, T.ArrayConstant1), | |
| 676 T.Union(T.ObjectConstant1, T.ArrayConstant2)), | |
| 677 T.Union( | |
| 678 T.Union(T.ObjectConstant1, T.ObjectConstant2), | |
| 679 T.ArrayConstant1)); | |
| 680 CheckEqual( | |
| 681 T.Union( | |
| 682 T.Union(T.Number, T.ArrayClass), | 918 T.Union(T.Number, T.ArrayClass), |
| 683 T.Union(T.SignedSmall, T.Array)), | 919 T.Union(T.SignedSmall, T.Array)), |
| 684 T.Union(T.Number, T.Array)); | 920 T.Union(T.Number, T.Array)); |
| 685 } | 921 } |
| 686 | 922 |
| 687 void Intersect() { | 923 void Intersect1() { |
| 688 // Bitset-bitset | 924 // Identity: Intersect(T, Any) = T |
| 689 CHECK(this->IsBitset(T.Intersect(T.Object, T.Number))); | 925 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 690 CHECK(this->IsBitset(T.Intersect(T.Object, T.Object))); | 926 TypeHandle type = *it; |
| 691 CHECK(this->IsBitset(T.Intersect(T.Any, T.None))); | 927 TypeHandle intersect_type = T.Intersect(type, T.Any); |
| 928 CheckEqual(intersect_type, type); |
| 929 } |
| 692 | 930 |
| 693 CheckEqual(T.Intersect(T.None, T.Number), T.None); | 931 // Domination: Intersect(T, None) = None |
| 694 CheckSub(T.Intersect(T.Object, T.Proxy), T.Representation); | 932 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 695 CheckEqual(T.Intersect(T.Name, T.String), T.Intersect(T.String, T.Name)); | 933 TypeHandle type = *it; |
| 696 CheckEqual(T.Intersect(T.UniqueName, T.String), T.InternalizedString); | 934 TypeHandle intersect_type = T.Intersect(type, T.None); |
| 935 CheckEqual(intersect_type, T.None); |
| 936 } |
| 697 | 937 |
| 698 // Class-class | 938 // Idempotence: Intersect(T, T) = T |
| 699 CHECK(this->IsClass(T.Intersect(T.ObjectClass, T.ObjectClass))); | 939 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 700 CHECK(this->IsBitset(T.Intersect(T.ObjectClass, T.ArrayClass))); | 940 TypeHandle type = *it; |
| 941 TypeHandle intersect_type = T.Intersect(type, type); |
| 942 CheckEqual(intersect_type, type); |
| 943 } |
| 701 | 944 |
| 702 CheckEqual(T.Intersect(T.ObjectClass, T.ObjectClass), T.ObjectClass); | 945 // Commutativity: Intersect(T1, T2) = Intersect(T2, T1) |
| 703 CheckEqual(T.Intersect(T.ObjectClass, T.ArrayClass), T.None); | 946 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 947 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 948 TypeHandle type1 = *it1; |
| 949 TypeHandle type2 = *it2; |
| 950 TypeHandle intersect12 = T.Intersect(type1, type2); |
| 951 TypeHandle intersect21 = T.Intersect(type2, type1); |
| 952 CheckEqual(intersect12, intersect21); |
| 953 } |
| 954 } |
| 704 | 955 |
| 705 // Constant-constant | 956 // Associativity: |
| 706 CHECK(this->IsConstant(T.Intersect(T.ObjectConstant1, T.ObjectConstant1))); | 957 // Intersect(T1, Intersect(T2, T3)) = Intersect(Intersect(T1, T2), T3) |
| 707 CHECK(this->IsConstant(T.Intersect(T.ArrayConstant1, T.ArrayConstant2))); | 958 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 708 CHECK(this->IsBitset(T.Intersect(T.ObjectConstant1, T.ObjectConstant2))); | 959 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 960 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { |
| 961 TypeHandle type1 = *it1; |
| 962 TypeHandle type2 = *it2; |
| 963 TypeHandle type3 = *it3; |
| 964 TypeHandle intersect12 = T.Intersect(type1, type2); |
| 965 TypeHandle intersect23 = T.Intersect(type2, type3); |
| 966 TypeHandle intersect1_23 = T.Intersect(type1, intersect23); |
| 967 TypeHandle intersect12_3 = T.Intersect(intersect12, type3); |
| 968 CheckEqual(intersect1_23, intersect12_3); |
| 969 } |
| 970 } |
| 971 } |
| 709 | 972 |
| 710 CheckEqual( | 973 // Join: Intersect(T1, T2)->Is(T1) and Intersect(T1, T2)->Is(T2) |
| 711 T.Intersect(T.ObjectConstant1, T.ObjectConstant1), T.ObjectConstant1); | 974 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 712 CheckEqual( | 975 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 713 T.Intersect(T.ArrayConstant1, T.ArrayConstant2), T.ArrayConstant1); | 976 TypeHandle type1 = *it1; |
| 714 CheckEqual(T.Intersect(T.ObjectConstant1, T.ObjectConstant2), T.None); | 977 TypeHandle type2 = *it2; |
| 978 TypeHandle intersect12 = T.Intersect(type1, type2); |
| 979 CHECK(intersect12->Is(type1)); |
| 980 CHECK(intersect12->Is(type2)); |
| 981 } |
| 982 } |
| 983 |
| 984 // Lower Boundedness: T1->Is(T2) implies Intersect(T1, T2) = T1 |
| 985 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 986 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 987 TypeHandle type1 = *it1; |
| 988 TypeHandle type2 = *it2; |
| 989 TypeHandle intersect12 = T.Intersect(type1, type2); |
| 990 if (type1->Is(type2)) CheckEqual(intersect12, type1); |
| 991 } |
| 992 } |
| 993 } |
| 994 |
| 995 void Intersect2() { |
| 996 // Monotonicity: T1->Is(T2) implies Intersect(T1, T3)->Is(Intersect(T2, T3)) |
| 997 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 998 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 999 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { |
| 1000 TypeHandle type1 = *it1; |
| 1001 TypeHandle type2 = *it2; |
| 1002 TypeHandle type3 = *it3; |
| 1003 TypeHandle intersect13 = T.Intersect(type1, type3); |
| 1004 TypeHandle intersect23 = T.Intersect(type2, type3); |
| 1005 CHECK(!type1->Is(type2) || intersect13->Is(intersect23)); |
| 1006 } |
| 1007 } |
| 1008 } |
| 1009 |
| 1010 // Monotonicity: T1->Is(T3) or T2->Is(T3) implies Intersect(T1, T2)->Is(T3) |
| 1011 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1012 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1013 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { |
| 1014 TypeHandle type1 = *it1; |
| 1015 TypeHandle type2 = *it2; |
| 1016 TypeHandle type3 = *it3; |
| 1017 TypeHandle intersect12 = T.Intersect(type1, type2); |
| 1018 CHECK(!(type1->Is(type3) || type2->Is(type3)) || |
| 1019 intersect12->Is(type3)); |
| 1020 } |
| 1021 } |
| 1022 } |
| 1023 |
| 1024 // Monotonicity: T1->Is(T2) and T1->Is(T3) implies T1->Is(Intersect(T2, T3)) |
| 1025 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1026 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1027 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { |
| 1028 TypeHandle type1 = *it1; |
| 1029 TypeHandle type2 = *it2; |
| 1030 TypeHandle type3 = *it3; |
| 1031 TypeHandle intersect23 = T.Intersect(type2, type3); |
| 1032 CHECK(!(type1->Is(type2) && type1->Is(type3)) || |
| 1033 type1->Is(intersect23)); |
| 1034 } |
| 1035 } |
| 1036 } |
| 715 | 1037 |
| 716 // Bitset-class | 1038 // Bitset-class |
| 717 CHECK(this->IsClass(T.Intersect(T.ObjectClass, T.Object))); | |
| 718 CHECK(this->IsBitset(T.Intersect(T.ObjectClass, T.Number))); | |
| 719 | |
| 720 CheckEqual(T.Intersect(T.ObjectClass, T.Object), T.ObjectClass); | 1039 CheckEqual(T.Intersect(T.ObjectClass, T.Object), T.ObjectClass); |
| 721 CheckSub(T.Intersect(T.ObjectClass, T.Array), T.Representation); | 1040 CheckSub(T.Intersect(T.ObjectClass, T.Array), T.Representation); |
| 722 CheckSub(T.Intersect(T.ObjectClass, T.Number), T.Representation); | 1041 CheckSub(T.Intersect(T.ObjectClass, T.Number), T.Representation); |
| 723 | 1042 |
| 724 // Bitset-constant | |
| 725 CHECK(this->IsBitset(T.Intersect(T.SignedSmall, T.Number))); | |
| 726 CHECK(this->IsConstant(T.Intersect(T.SmiConstant, T.Number))); | |
| 727 CHECK(this->IsConstant(T.Intersect(T.ObjectConstant1, T.Object))); | |
| 728 | |
| 729 CheckEqual(T.Intersect(T.SignedSmall, T.Number), T.SignedSmall); | |
| 730 CheckEqual(T.Intersect(T.SmiConstant, T.Number), T.SmiConstant); | |
| 731 CheckEqual(T.Intersect(T.ObjectConstant1, T.Object), T.ObjectConstant1); | |
| 732 | |
| 733 // Class-constant | |
| 734 CHECK(this->IsBitset(T.Intersect(T.ObjectConstant1, T.ObjectClass))); | |
| 735 CHECK(this->IsBitset(T.Intersect(T.ArrayClass, T.ObjectConstant2))); | |
| 736 | |
| 737 CheckEqual(T.Intersect(T.ObjectConstant1, T.ObjectClass), T.None); | |
| 738 CheckEqual(T.Intersect(T.ArrayClass, T.ObjectConstant2), T.None); | |
| 739 | |
| 740 // Bitset-union | 1043 // Bitset-union |
| 741 CHECK(this->IsUnion( | |
| 742 T.Intersect(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)))); | |
| 743 CHECK(this->IsBitset( | |
| 744 T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant2), T.Number))); | |
| 745 | |
| 746 CheckEqual( | 1044 CheckEqual( |
| 747 T.Intersect(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)), | 1045 T.Intersect(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)), |
| 748 T.Union(T.ObjectConstant1, T.ObjectClass)); | 1046 T.Union(T.ObjectConstant1, T.ObjectClass)); |
| 749 CheckEqual( | 1047 CheckEqual( |
| 750 T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number), | 1048 T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number), |
| 751 T.None); | 1049 T.None); |
| 752 | 1050 |
| 1051 // Class-constant |
| 1052 CheckEqual(T.Intersect(T.ObjectConstant1, T.ObjectClass), T.None); |
| 1053 CheckEqual(T.Intersect(T.ArrayClass, T.ObjectConstant2), T.None); |
| 1054 |
| 753 // Class-union | 1055 // Class-union |
| 754 CHECK(this->IsClass( | |
| 755 T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass))); | |
| 756 CHECK(this->IsClass( | |
| 757 T.Intersect(T.Union(T.Object, T.SmiConstant), T.ArrayClass))); | |
| 758 CHECK(this->IsBitset( | |
| 759 T.Intersect(T.Union(T.ObjectClass, T.ArrayConstant1), T.ArrayClass))); | |
| 760 | |
| 761 CheckEqual( | 1056 CheckEqual( |
| 762 T.Intersect(T.ArrayClass, T.Union(T.ObjectConstant2, T.ArrayClass)), | 1057 T.Intersect(T.ArrayClass, T.Union(T.ObjectConstant2, T.ArrayClass)), |
| 763 T.ArrayClass); | 1058 T.ArrayClass); |
| 764 CheckEqual( | 1059 CheckEqual( |
| 765 T.Intersect(T.ArrayClass, T.Union(T.Object, T.SmiConstant)), | 1060 T.Intersect(T.ArrayClass, T.Union(T.Object, T.SmiConstant)), |
| 766 T.ArrayClass); | 1061 T.ArrayClass); |
| 767 CheckEqual( | 1062 CheckEqual( |
| 768 T.Intersect(T.Union(T.ObjectClass, T.ArrayConstant1), T.ArrayClass), | 1063 T.Intersect(T.Union(T.ObjectClass, T.ArrayConstant), T.ArrayClass), |
| 769 T.None); | 1064 T.None); |
| 770 | 1065 |
| 771 // Constant-union | 1066 // Constant-union |
| 772 CHECK(this->IsConstant(T.Intersect( | |
| 773 T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)))); | |
| 774 CHECK(this->IsConstant(T.Intersect( | |
| 775 T.Union(T.Number, T.ObjectClass), T.SmiConstant))); | |
| 776 CHECK(this->IsBitset(T.Intersect( | |
| 777 T.Union(T.ArrayConstant1, T.ObjectClass), T.ObjectConstant1))); | |
| 778 | |
| 779 CheckEqual( | 1067 CheckEqual( |
| 780 T.Intersect( | 1068 T.Intersect( |
| 781 T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)), | 1069 T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)), |
| 782 T.ObjectConstant1); | 1070 T.ObjectConstant1); |
| 783 CheckEqual( | 1071 CheckEqual( |
| 784 T.Intersect(T.SmiConstant, T.Union(T.Number, T.ObjectConstant2)), | 1072 T.Intersect(T.SmiConstant, T.Union(T.Number, T.ObjectConstant2)), |
| 785 T.SmiConstant); | 1073 T.SmiConstant); |
| 786 CheckEqual( | 1074 CheckEqual( |
| 787 T.Intersect( | 1075 T.Intersect( |
| 788 T.Union(T.ArrayConstant1, T.ObjectClass), T.ObjectConstant1), | 1076 T.Union(T.ArrayConstant, T.ObjectClass), T.ObjectConstant1), |
| 789 T.None); | 1077 T.None); |
| 790 | 1078 |
| 791 // Union-union | 1079 // Union-union |
| 792 CHECK(this->IsUnion(T.Intersect( | |
| 793 T.Union(T.Number, T.ArrayClass), T.Union(T.Signed32, T.Array)))); | |
| 794 CHECK(this->IsBitset(T.Intersect( | |
| 795 T.Union(T.Number, T.ObjectClass), T.Union(T.Signed32, T.Array)))); | |
| 796 | |
| 797 CheckEqual( | 1080 CheckEqual( |
| 798 T.Intersect( | 1081 T.Intersect( |
| 799 T.Union(T.Number, T.ArrayClass), | 1082 T.Union(T.Number, T.ArrayClass), |
| 800 T.Union(T.SignedSmall, T.Array)), | 1083 T.Union(T.SignedSmall, T.Array)), |
| 801 T.Union(T.SignedSmall, T.ArrayClass)); | 1084 T.Union(T.SignedSmall, T.ArrayClass)); |
| 802 CheckEqual( | 1085 CheckEqual( |
| 803 T.Intersect( | 1086 T.Intersect( |
| 804 T.Union(T.Number, T.ObjectClass), | 1087 T.Union(T.Number, T.ObjectClass), |
| 805 T.Union(T.Signed32, T.Array)), | 1088 T.Union(T.Signed32, T.Array)), |
| 806 T.Signed32); | 1089 T.Signed32); |
| 807 CheckEqual( | 1090 CheckEqual( |
| 808 T.Intersect( | 1091 T.Intersect( |
| 809 T.Union(T.ObjectConstant2, T.ObjectConstant1), | 1092 T.Union(T.ObjectConstant2, T.ObjectConstant1), |
| 810 T.Union(T.ObjectConstant1, T.ObjectConstant2)), | 1093 T.Union(T.ObjectConstant1, T.ObjectConstant2)), |
| 811 T.Union(T.ObjectConstant2, T.ObjectConstant1)); | 1094 T.Union(T.ObjectConstant2, T.ObjectConstant1)); |
| 812 CheckEqual( | 1095 CheckEqual( |
| 813 T.Intersect( | 1096 T.Intersect( |
| 814 T.Union( | 1097 T.Union( |
| 815 T.Union(T.ObjectConstant2, T.ObjectConstant1), T.ArrayClass), | 1098 T.Union(T.ObjectConstant2, T.ObjectConstant1), T.ArrayClass), |
| 816 T.Union( | 1099 T.Union( |
| 817 T.ObjectConstant1, | 1100 T.ObjectConstant1, |
| 818 T.Union(T.ArrayConstant1, T.ObjectConstant2))), | 1101 T.Union(T.ArrayConstant, T.ObjectConstant2))), |
| 819 T.Union(T.ObjectConstant2, T.ObjectConstant1)); | 1102 T.Union(T.ObjectConstant2, T.ObjectConstant1)); |
| 820 CheckEqual( | |
| 821 T.Intersect( | |
| 822 T.Union(T.ObjectConstant2, T.ArrayConstant1), | |
| 823 T.Union(T.ObjectConstant1, T.ArrayConstant2)), | |
| 824 T.ArrayConstant1); | |
| 825 } | 1103 } |
| 826 | 1104 |
| 827 template<class Type2, class TypeHandle2, class Region2, class Rep2> | 1105 template<class Type2, class TypeHandle2, class Region2, class Rep2> |
| 828 void Convert() { | 1106 void Convert() { |
| 829 Types<Type2, TypeHandle2, Region2> T2( | 1107 Types<Type2, TypeHandle2, Region2> T2( |
| 830 Rep2::ToRegion(&zone, isolate), isolate); | 1108 Rep2::ToRegion(&zone, isolate), isolate); |
| 831 for (int i = 0; i < 100; ++i) { | 1109 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 832 TypeHandle type = T.Fuzz(); | 1110 TypeHandle type1 = *it; |
| 833 CheckEqual(type, | 1111 TypeHandle2 type2 = T2.template Convert<Type>(type1); |
| 834 T.template Convert<Type2>(T2.template Convert<Type>(type))); | 1112 TypeHandle type3 = T.template Convert<Type2>(type2); |
| 1113 CheckEqual(type1, type3); |
| 835 } | 1114 } |
| 836 } | 1115 } |
| 837 }; | 1116 }; |
| 838 | 1117 |
| 839 typedef Tests<Type, Type*, Zone, ZoneRep> ZoneTests; | 1118 typedef Tests<Type, Type*, Zone, ZoneRep> ZoneTests; |
| 840 typedef Tests<HeapType, Handle<HeapType>, Isolate, HeapRep> HeapTests; | 1119 typedef Tests<HeapType, Handle<HeapType>, Isolate, HeapRep> HeapTests; |
| 841 | 1120 |
| 842 | 1121 |
| 843 TEST(Bitset) { | 1122 TEST(BitsetType) { |
| 844 CcTest::InitializeVM(); | 1123 CcTest::InitializeVM(); |
| 845 ZoneTests().Bitset(); | 1124 ZoneTests().Bitset(); |
| 846 HeapTests().Bitset(); | 1125 HeapTests().Bitset(); |
| 847 } | 1126 } |
| 848 | 1127 |
| 849 | 1128 |
| 850 TEST(Class) { | 1129 TEST(ClassType) { |
| 851 CcTest::InitializeVM(); | 1130 CcTest::InitializeVM(); |
| 852 ZoneTests().Class(); | 1131 ZoneTests().Class(); |
| 853 HeapTests().Class(); | 1132 HeapTests().Class(); |
| 854 } | 1133 } |
| 855 | 1134 |
| 856 | 1135 |
| 857 TEST(Constant) { | 1136 TEST(ConstantType) { |
| 858 CcTest::InitializeVM(); | 1137 CcTest::InitializeVM(); |
| 859 ZoneTests().Constant(); | 1138 ZoneTests().Constant(); |
| 860 HeapTests().Constant(); | 1139 HeapTests().Constant(); |
| 861 } | 1140 } |
| 862 | 1141 |
| 863 | 1142 |
| 1143 TEST(Of) { |
| 1144 CcTest::InitializeVM(); |
| 1145 ZoneTests().Of(); |
| 1146 HeapTests().Of(); |
| 1147 } |
| 1148 |
| 1149 |
| 864 TEST(Is) { | 1150 TEST(Is) { |
| 865 CcTest::InitializeVM(); | 1151 CcTest::InitializeVM(); |
| 866 ZoneTests().Is(); | 1152 ZoneTests().Is(); |
| 867 HeapTests().Is(); | 1153 HeapTests().Is(); |
| 868 } | 1154 } |
| 869 | 1155 |
| 870 | 1156 |
| 871 TEST(Maybe) { | 1157 TEST(Maybe) { |
| 872 CcTest::InitializeVM(); | 1158 CcTest::InitializeVM(); |
| 873 ZoneTests().Maybe(); | 1159 ZoneTests().Maybe(); |
| 874 HeapTests().Maybe(); | 1160 HeapTests().Maybe(); |
| 875 } | 1161 } |
| 876 | 1162 |
| 877 | 1163 |
| 878 TEST(Union) { | 1164 TEST(Union1) { |
| 879 CcTest::InitializeVM(); | 1165 CcTest::InitializeVM(); |
| 880 ZoneTests().Union(); | 1166 ZoneTests().Union1(); |
| 881 HeapTests().Union(); | 1167 HeapTests().Union1(); |
| 882 } | 1168 } |
| 883 | 1169 |
| 884 | 1170 |
| 885 TEST(Intersect) { | 1171 TEST(Union2) { |
| 886 CcTest::InitializeVM(); | 1172 CcTest::InitializeVM(); |
| 887 ZoneTests().Intersect(); | 1173 ZoneTests().Union2(); |
| 888 HeapTests().Intersect(); | 1174 HeapTests().Union2(); |
| 889 } | 1175 } |
| 890 | 1176 |
| 891 | 1177 |
| 1178 TEST(Intersect1) { |
| 1179 CcTest::InitializeVM(); |
| 1180 ZoneTests().Intersect1(); |
| 1181 HeapTests().Intersect1(); |
| 1182 } |
| 1183 |
| 1184 |
| 1185 TEST(Intersect2) { |
| 1186 CcTest::InitializeVM(); |
| 1187 ZoneTests().Intersect2(); |
| 1188 HeapTests().Intersect2(); |
| 1189 } |
| 1190 |
| 1191 |
| 892 TEST(Convert) { | 1192 TEST(Convert) { |
| 893 CcTest::InitializeVM(); | 1193 CcTest::InitializeVM(); |
| 894 ZoneTests().Convert<HeapType, Handle<HeapType>, Isolate, HeapRep>(); | 1194 ZoneTests().Convert<HeapType, Handle<HeapType>, Isolate, HeapRep>(); |
| 895 HeapTests().Convert<Type, Type*, Zone, ZoneRep>(); | 1195 HeapTests().Convert<Type, Type*, Zone, ZoneRep>(); |
| 896 } | 1196 } |
| OLD | NEW |