template<class Config>
int TypeImpl<Config>::LubBitset(i::Object* value) {
- if (value->IsSmi()) return kSmi;
+ if (value->IsSmi()) return kSignedSmall & kTaggedInt;
i::Map* map = i::HeapObject::cast(value)->map();
if (map->instance_type() == HEAP_NUMBER_TYPE) {
int32_t i;
uint32_t u;
- if (value->ToInt32(&i)) return Smi::IsValid(i) ? kSmi : kOtherSigned32;
- if (value->ToUint32(&u)) return kUnsigned32;
- return kDouble;
+ return kTaggedPtr & (
+ value->ToInt32(&i) ? (Smi::IsValid(i) ? kSignedSmall : kOtherSigned32) :
+ value->ToUint32(&u) ? kUnsigned32 : kFloat);
}
if (map->instance_type() == ODDBALL_TYPE) {
if (value->IsUndefined()) return kUndefined;
case ODDBALL_TYPE:
return kOddball;
case HEAP_NUMBER_TYPE:
- return kDouble;
+ return kFloat & kTaggedPtr;
case JS_VALUE_TYPE:
case JS_DATE_TYPE:
case JS_OBJECT_TYPE:
case EXECUTABLE_ACCESSOR_INFO_TYPE:
case ACCESSOR_PAIR_TYPE:
case FIXED_ARRAY_TYPE:
- return kInternal;
+ return kInternal & kTaggedPtr;
default:
UNREACHABLE();
return kNone;
template<class Config>
typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::OfCurrently(
i::Handle<i::Object> value, Region* region) {
- if (value->IsSmi()) return Smi(region);
- i::Map* map = i::HeapObject::cast(*value)->map();
- if (map->instance_type() == HEAP_NUMBER_TYPE ||
- map->instance_type() == ODDBALL_TYPE) {
+ if (value->IsSmi() ||
+ i::HeapObject::cast(*value)->map()->instance_type() == HEAP_NUMBER_TYPE ||
+ i::HeapObject::cast(*value)->map()->instance_type() == ODDBALL_TYPE) {
return Of(value, region);
}
- return Class(i::handle(map), region);
+ return Class(i::handle(i::HeapObject::cast(*value)->map()), region);
}
bool TypeImpl<Config>::Maybe(TypeImpl* that) {
// Fast path for bitsets.
if (this->IsBitset()) {
- return (this->AsBitset() & that->LubBitset()) != 0;
+ return IsInhabited(this->AsBitset() & that->LubBitset());
}
if (that->IsBitset()) {
- return (this->LubBitset() & that->AsBitset()) != 0;
+ return IsInhabited(this->LubBitset() & that->AsBitset());
}
// (T1 \/ ... \/ Tn) overlaps T <=> (T1 overlaps T) \/ ... \/ (Tn overlaps T)
// TODO(rossberg): this does not belong here.
Representation Representation::FromType(Type* type) {
if (type->Is(Type::None())) return Representation::None();
- if (type->Is(Type::Smi())) return Representation::Smi();
+ if (type->Is(Type::SignedSmall())) return Representation::Smi();
if (type->Is(Type::Signed32())) return Representation::Integer32();
if (type->Is(Type::Number())) return Representation::Double();
return Representation::Tagged();
#ifdef OBJECT_PRINT
template<class Config>
-void TypeImpl<Config>::TypePrint() {
- TypePrint(stdout);
+void TypeImpl<Config>::TypePrint(PrintDimension dim) {
+ TypePrint(stdout, dim);
PrintF(stdout, "\n");
Flush(stdout);
}
template<class Config>
const char* TypeImpl<Config>::bitset_name(int bitset) {
switch (bitset) {
- #define PRINT_COMPOSED_TYPE(type, value) case k##type: return #type;
- BITSET_TYPE_LIST(PRINT_COMPOSED_TYPE)
+ case kAny & kRepresentation: return "Any";
+ #define PRINT_COMPOSED_TYPE(type, value) \
+ case k##type & kRepresentation: return #type;
+ REPRESENTATION_BITSET_TYPE_LIST(PRINT_COMPOSED_TYPE)
#undef PRINT_COMPOSED_TYPE
+
+ #define PRINT_COMPOSED_TYPE(type, value) \
+ case k##type & kSemantic: return #type;
+ SEMANTIC_BITSET_TYPE_LIST(PRINT_COMPOSED_TYPE)
+ #undef PRINT_COMPOSED_TYPE
+
default:
return NULL;
}
template<class Config>
-void TypeImpl<Config>::TypePrint(FILE* out) {
+void TypeImpl<Config>::BitsetTypePrint(FILE* out, int bitset) {
+ const char* name = bitset_name(bitset);
+ if (name != NULL) {
+ PrintF(out, "%s", name);
+ } else {
+ static const int named_bitsets[] = {
+ #define BITSET_CONSTANT(type, value) k##type & kRepresentation,
+ REPRESENTATION_BITSET_TYPE_LIST(BITSET_CONSTANT)
+ #undef BITSET_CONSTANT
+
+ #define BITSET_CONSTANT(type, value) k##type & kSemantic,
+ SEMANTIC_BITSET_TYPE_LIST(BITSET_CONSTANT)
+ #undef BITSET_CONSTANT
+ };
+
+ bool is_first = true;
+ PrintF(out, "(");
+ for (int i(ARRAY_SIZE(named_bitsets) - 1); bitset != 0 && i >= 0; --i) {
+ int subset = named_bitsets[i];
+ if ((bitset & subset) == subset) {
+ if (!is_first) PrintF(out, " | ");
+ is_first = false;
+ PrintF(out, "%s", bitset_name(subset));
+ bitset -= subset;
+ }
+ }
+ ASSERT(bitset == 0);
+ PrintF(out, ")");
+ }
+}
+
+
+template<class Config>
+void TypeImpl<Config>::TypePrint(FILE* out, PrintDimension dim) {
if (this->IsBitset()) {
int bitset = this->AsBitset();
- const char* name = bitset_name(bitset);
- if (name != NULL) {
- PrintF(out, "%s", name);
- } else {
- bool is_first = true;
- PrintF(out, "(");
- for (int mask = 1; mask != 0; mask = mask << 1) {
- if ((bitset & mask) != 0) {
- if (!is_first) PrintF(out, " | ");
- is_first = false;
- PrintF(out, "%s", bitset_name(mask));
- }
- }
- PrintF(out, ")");
+ switch (dim) {
+ case BOTH_DIMS:
+ BitsetTypePrint(out, bitset & kSemantic);
+ PrintF("/");
+ BitsetTypePrint(out, bitset & kRepresentation);
+ break;
+ case SEMANTIC_DIM:
+ BitsetTypePrint(out, bitset & kSemantic);
+ break;
+ case REPRESENTATION_DIM:
+ BitsetTypePrint(out, bitset & kRepresentation);
+ break;
}
} else if (this->IsConstant()) {
PrintF(out, "Constant(%p : ", static_cast<void*>(*this->AsConstant()));
// can express class types (a.k.a. specific maps) and singleton types (i.e.,
// concrete constants).
//
-// The following equations and inequations hold:
+// Types consist of two dimensions: semantic (value range) and representation.
+// Both are related through subtyping.
+//
+// The following equations and inequations hold for the semantic axis:
//
// None <= T
// T <= Any
// UniqueName = InternalizedString \/ Symbol
// InternalizedString < String
//
-// Allocated = Receiver \/ Number \/ Name
-// Detectable = Allocated - Undetectable
-// Undetectable < Object
// Receiver = Object \/ Proxy
// Array < Object
// Function < Object
// RegExp < Object
+// Undetectable < Object
+// Detectable = Receiver \/ Number \/ Name - Undetectable
//
// Class(map) < T iff instance_type(map) < T
// Constant(x) < T iff instance_type(map(x)) < T
// TODO(rossberg): the latter is not currently true for proxies, because of fix,
// but will hold once we implement direct proxies.
//
+// For the representation axis, the following holds:
+//
+// None <= R
+// R <= Any
+//
+// UntaggedInt <= UntaggedInt8 \/ UntaggedInt16 \/ UntaggedInt32)
+// UntaggedFloat <= UntaggedFloat32 \/ UntaggedFloat64
+// UntaggedNumber <= UntaggedInt \/ UntaggedFloat
+// Untagged <= UntaggedNumber \/ UntaggedPtr
+// Tagged <= TaggedInt \/ TaggedPtr
+//
+// Subtyping relates the two dimensions, for example:
+//
+// Number <= Tagged \/ UntaggedNumber
+// Object <= TaggedPtr \/ UntaggedPtr
+//
+// That holds because the semantic type constructors defined by the API create
+// types that allow for all possible representations, and dually, the ones for
+// representation types initially include all semantic ranges. Representations
+// can then e.g. be narrowed for a given semantic type using intersection:
+//
+// SignedSmall /\ TaggedInt (a 'smi')
+// Number /\ TaggedPtr (a heap number)
+//
// There are two main functions for testing types:
//
// T1->Is(T2) -- tests whether T1 is included in T2 (i.e., T1 <= T2)
// T1->Maybe(T2) -- tests whether T1 and T2 overlap (i.e., T1 /\ T2 =/= 0)
//
// Typically, the former is to be used to select representations (e.g., via
-// T->Is(Integer31())), and the to check whether a specific case needs handling
-// (e.g., via T->Maybe(Number())).
+// T->Is(SignedSmall())), and the latter to check whether a specific case needs
+// handling (e.g., via T->Maybe(Number())).
//
// There is no functionality to discover whether a type is a leaf in the
// lattice. That is intentional. It should always be possible to refine the
// lattice (e.g., splitting up number types further) without invalidating any
// existing assumptions or tests.
-//
// Consequently, do not use pointer equality for type tests, always use Is!
//
// Internally, all 'primitive' types, and their unions, are represented as
// them. For zone types, no query method touches the heap, only constructors do.
-#define BITSET_TYPE_LIST(V) \
- V(None, 0) \
- V(Null, 1 << 0) \
- V(Undefined, 1 << 1) \
- V(Boolean, 1 << 2) \
- V(Smi, 1 << 3) \
- V(OtherSigned32, 1 << 4) \
- V(Unsigned32, 1 << 5) \
- V(Double, 1 << 6) \
- V(Symbol, 1 << 7) \
- V(InternalizedString, 1 << 8) \
- V(OtherString, 1 << 9) \
- V(Undetectable, 1 << 10) \
- V(Array, 1 << 11) \
- V(Function, 1 << 12) \
- V(RegExp, 1 << 13) \
- V(OtherObject, 1 << 14) \
- V(Proxy, 1 << 15) \
- V(Internal, 1 << 16) \
+#define MASK_BITSET_TYPE_LIST(V) \
+ V(Representation, static_cast<int>(0xff800000)) \
+ V(Semantic, static_cast<int>(0x007fffff))
+
+#define REPRESENTATION(k) ((k) & kRepresentation)
+#define SEMANTIC(k) ((k) & kSemantic)
+
+#define REPRESENTATION_BITSET_TYPE_LIST(V) \
+ V(None, 0) \
+ V(UntaggedInt8, 1 << 23 | kSemantic) \
+ V(UntaggedInt16, 1 << 24 | kSemantic) \
+ V(UntaggedInt32, 1 << 25 | kSemantic) \
+ V(UntaggedFloat32, 1 << 26 | kSemantic) \
+ V(UntaggedFloat64, 1 << 27 | kSemantic) \
+ V(UntaggedPtr, 1 << 28 | kSemantic) \
+ V(TaggedInt, 1 << 29 | kSemantic) \
+ V(TaggedPtr, -1 << 30 | kSemantic) /* MSB has to be sign-extended */ \
+ \
+ V(UntaggedInt, kUntaggedInt8 | kUntaggedInt16 | kUntaggedInt32) \
+ V(UntaggedFloat, kUntaggedFloat32 | kUntaggedFloat64) \
+ V(UntaggedNumber, kUntaggedInt | kUntaggedFloat) \
+ V(Untagged, kUntaggedNumber | kUntaggedPtr) \
+ V(Tagged, kTaggedInt | kTaggedPtr)
+
+#define SEMANTIC_BITSET_TYPE_LIST(V) \
+ V(Null, 1 << 0 | REPRESENTATION(kTaggedPtr)) \
+ V(Undefined, 1 << 1 | REPRESENTATION(kTaggedPtr)) \
+ V(Boolean, 1 << 2 | REPRESENTATION(kTaggedPtr)) \
+ V(SignedSmall, 1 << 3 | REPRESENTATION(kTagged | kUntaggedNumber)) \
+ V(OtherSigned32, 1 << 4 | REPRESENTATION(kTagged | kUntaggedNumber)) \
+ V(Unsigned32, 1 << 5 | REPRESENTATION(kTagged | kUntaggedNumber)) \
+ V(Float, 1 << 6 | REPRESENTATION(kTagged | kUntaggedNumber)) \
+ V(Symbol, 1 << 7 | REPRESENTATION(kTaggedPtr)) \
+ V(InternalizedString, 1 << 8 | REPRESENTATION(kTaggedPtr)) \
+ V(OtherString, 1 << 9 | REPRESENTATION(kTaggedPtr)) \
+ V(Undetectable, 1 << 10 | REPRESENTATION(kTaggedPtr)) \
+ V(Array, 1 << 11 | REPRESENTATION(kTaggedPtr)) \
+ V(Function, 1 << 12 | REPRESENTATION(kTaggedPtr)) \
+ V(RegExp, 1 << 13 | REPRESENTATION(kTaggedPtr)) \
+ V(OtherObject, 1 << 14 | REPRESENTATION(kTaggedPtr)) \
+ V(Proxy, 1 << 15 | REPRESENTATION(kTaggedPtr)) \
+ V(Internal, 1 << 16 | REPRESENTATION(kTagged | kUntagged)) \
\
- V(Oddball, kBoolean | kNull | kUndefined) \
- V(Signed32, kSmi | kOtherSigned32) \
- V(Number, kSigned32 | kUnsigned32 | kDouble) \
- V(String, kInternalizedString | kOtherString) \
- V(UniqueName, kSymbol | kInternalizedString) \
- V(Name, kSymbol | kString) \
- V(NumberOrString, kNumber | kString) \
- V(Object, kUndetectable | kArray | kFunction | \
- kRegExp | kOtherObject) \
- V(Receiver, kObject | kProxy) \
- V(Allocated, kDouble | kName | kReceiver) \
- V(Any, kOddball | kNumber | kAllocated | kInternal) \
- V(NonNumber, kAny - kNumber) \
- V(Detectable, kAllocated - kUndetectable)
+ V(Oddball, kBoolean | kNull | kUndefined) \
+ V(Signed32, kSignedSmall | kOtherSigned32) \
+ V(Number, kSigned32 | kUnsigned32 | kFloat) \
+ V(String, kInternalizedString | kOtherString) \
+ V(UniqueName, kSymbol | kInternalizedString) \
+ V(Name, kSymbol | kString) \
+ V(NumberOrString, kNumber | kString) \
+ V(DetectableObject, kArray | kFunction | kRegExp | kOtherObject) \
+ V(DetectableReceiver, kDetectableObject | kProxy) \
+ V(Detectable, kDetectableReceiver | kNumber | kName) \
+ V(Object, kDetectableObject | kUndetectable) \
+ V(Receiver, kObject | kProxy) \
+ V(NonNumber, kOddball | kName | kReceiver | kInternal) \
+ V(Any, kNumber | kNonNumber)
+
+#define BITSET_TYPE_LIST(V) \
+ MASK_BITSET_TYPE_LIST(V) \
+ REPRESENTATION_BITSET_TYPE_LIST(V) \
+ SEMANTIC_BITSET_TYPE_LIST(V)
// struct Config {
typename OtherTypeImpl::TypeHandle type, Region* region);
#ifdef OBJECT_PRINT
- void TypePrint();
- void TypePrint(FILE* out);
+ enum PrintDimension { BOTH_DIMS, SEMANTIC_DIM, REPRESENTATION_DIM };
+ void TypePrint(PrintDimension = BOTH_DIMS);
+ void TypePrint(FILE* out, PrintDimension = BOTH_DIMS);
#endif
private:
bool SlowIs(TypeImpl* that);
+ static bool IsInhabited(int bitset) {
+ return (bitset & kRepresentation) && (bitset & kSemantic);
+ }
+
int LubBitset(); // least upper bound that's a bitset
int GlbBitset(); // greatest lower bound that's a bitset
#ifdef OBJECT_PRINT
static const char* bitset_name(int bitset);
+ static void BitsetTypePrint(FILE* out, int bitset);
#endif
};
class Types {
public:
Types(Region* region, Isolate* isolate) :
+ Representation(Type::Representation(region)),
+ Semantic(Type::Semantic(region)),
None(Type::None(region)),
Any(Type::Any(region)),
Oddball(Type::Oddball(region)),
Null(Type::Null(region)),
Undefined(Type::Undefined(region)),
Number(Type::Number(region)),
- Smi(Type::Smi(region)),
+ SignedSmall(Type::SignedSmall(region)),
Signed32(Type::Signed32(region)),
- Double(Type::Double(region)),
+ Float(Type::Float(region)),
Name(Type::Name(region)),
UniqueName(Type::UniqueName(region)),
String(Type::String(region)),
ArrayConstant2 = Type::Constant(array, region);
}
+ TypeHandle Representation;
+ TypeHandle Semantic;
TypeHandle None;
TypeHandle Any;
TypeHandle Oddball;
TypeHandle Null;
TypeHandle Undefined;
TypeHandle Number;
- TypeHandle Smi;
+ TypeHandle SignedSmall;
TypeHandle Signed32;
- TypeHandle Double;
+ TypeHandle Float;
TypeHandle Name;
TypeHandle UniqueName;
TypeHandle String;
T(Rep::ToRegion(&zone, isolate), isolate) {
}
- static void CheckEqual(TypeHandle type1, TypeHandle type2) {
+ void CheckEqual(TypeHandle type1, TypeHandle type2) {
CHECK_EQ(Rep::IsBitset(type1), Rep::IsBitset(type2));
CHECK_EQ(Rep::IsClass(type1), Rep::IsClass(type2));
CHECK_EQ(Rep::IsConstant(type1), Rep::IsConstant(type2));
CHECK(type2->Is(type1));
}
- static void CheckSub(TypeHandle type1, TypeHandle type2) {
+ void CheckSub(TypeHandle type1, TypeHandle type2) {
CHECK(type1->Is(type2));
CHECK(!type2->Is(type1));
if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) {
}
}
- static void CheckUnordered(TypeHandle type1, TypeHandle type2) {
+ void CheckUnordered(TypeHandle type1, TypeHandle type2) {
CHECK(!type1->Is(type2));
CHECK(!type2->Is(type1));
if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) {
}
}
- static void CheckOverlap(TypeHandle type1, TypeHandle type2) {
+ void CheckOverlap(TypeHandle type1, TypeHandle type2, TypeHandle mask) {
CHECK(type1->Maybe(type2));
CHECK(type2->Maybe(type1));
if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) {
- CHECK_NE(0, Rep::AsBitset(type1) & Rep::AsBitset(type2));
+ CHECK_NE(0,
+ Rep::AsBitset(type1) & Rep::AsBitset(type2) & Rep::AsBitset(mask));
}
}
- static void CheckDisjoint(TypeHandle type1, TypeHandle type2) {
+ void CheckDisjoint(TypeHandle type1, TypeHandle type2, TypeHandle mask) {
CHECK(!type1->Is(type2));
CHECK(!type2->Is(type1));
CHECK(!type1->Maybe(type2));
CHECK(!type2->Maybe(type1));
if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) {
- CHECK_EQ(0, Rep::AsBitset(type1) & Rep::AsBitset(type2));
+ CHECK_EQ(0,
+ Rep::AsBitset(type1) & Rep::AsBitset(type2) & Rep::AsBitset(mask));
}
}
CHECK(this->IsBitset(T.Union(T.String, T.Receiver)));
CHECK_EQ(0, this->AsBitset(T.None));
- CHECK_EQ(this->AsBitset(T.Number) | this->AsBitset(T.String),
- this->AsBitset(T.Union(T.String, T.Number)));
- CHECK_EQ(this->AsBitset(T.Receiver),
- this->AsBitset(T.Union(T.Receiver, T.Object)));
+ CHECK_EQ(
+ this->AsBitset(T.Number) | this->AsBitset(T.String),
+ this->AsBitset(T.Union(T.String, T.Number)));
+ CHECK_EQ(
+ this->AsBitset(T.Receiver),
+ this->AsBitset(T.Union(T.Receiver, T.Object)));
}
void Class() {
CheckUnordered(T.Boolean, T.Undefined);
CheckSub(T.Number, T.Any);
- CheckSub(T.Smi, T.Number);
+ CheckSub(T.SignedSmall, T.Number);
CheckSub(T.Signed32, T.Number);
- CheckSub(T.Double, T.Number);
- CheckSub(T.Smi, T.Signed32);
- CheckUnordered(T.Smi, T.Double);
- CheckUnordered(T.Signed32, T.Double);
+ CheckSub(T.Float, T.Number);
+ CheckSub(T.SignedSmall, T.Signed32);
+ CheckUnordered(T.SignedSmall, T.Float);
+ CheckUnordered(T.Signed32, T.Float);
CheckSub(T.Name, T.Any);
CheckSub(T.UniqueName, T.Any);
CheckSub(T.ArrayClass, T.Object);
CheckUnordered(T.ObjectClass, T.ArrayClass);
- CheckSub(T.SmiConstant, T.Smi);
+ CheckSub(T.SmiConstant, T.SignedSmall);
CheckSub(T.SmiConstant, T.Signed32);
CheckSub(T.SmiConstant, T.Number);
CheckSub(T.ObjectConstant1, T.Object);
}
void Maybe() {
- CheckOverlap(T.Any, T.Any);
- CheckOverlap(T.Object, T.Object);
-
- CheckOverlap(T.Oddball, T.Any);
- CheckOverlap(T.Boolean, T.Oddball);
- CheckOverlap(T.Null, T.Oddball);
- CheckOverlap(T.Undefined, T.Oddball);
- CheckDisjoint(T.Boolean, T.Null);
- CheckDisjoint(T.Undefined, T.Null);
- CheckDisjoint(T.Boolean, T.Undefined);
-
- CheckOverlap(T.Number, T.Any);
- CheckOverlap(T.Smi, T.Number);
- CheckOverlap(T.Double, T.Number);
- CheckDisjoint(T.Signed32, T.Double);
-
- CheckOverlap(T.Name, T.Any);
- CheckOverlap(T.UniqueName, T.Any);
- CheckOverlap(T.UniqueName, T.Name);
- CheckOverlap(T.String, T.Name);
- CheckOverlap(T.InternalizedString, T.String);
- CheckOverlap(T.InternalizedString, T.UniqueName);
- CheckOverlap(T.InternalizedString, T.Name);
- CheckOverlap(T.Symbol, T.UniqueName);
- CheckOverlap(T.Symbol, T.Name);
- CheckOverlap(T.String, T.UniqueName);
- CheckDisjoint(T.String, T.Symbol);
- CheckDisjoint(T.InternalizedString, T.Symbol);
-
- CheckOverlap(T.Receiver, T.Any);
- CheckOverlap(T.Object, T.Any);
- CheckOverlap(T.Object, T.Receiver);
- CheckOverlap(T.Array, T.Object);
- CheckOverlap(T.Function, T.Object);
- CheckOverlap(T.Proxy, T.Receiver);
- CheckDisjoint(T.Object, T.Proxy);
- CheckDisjoint(T.Array, T.Function);
-
- CheckOverlap(T.ObjectClass, T.Any);
- CheckOverlap(T.ObjectConstant1, T.Any);
-
- CheckOverlap(T.ObjectClass, T.Object);
- CheckOverlap(T.ArrayClass, T.Object);
- CheckOverlap(T.ObjectClass, T.ObjectClass);
- CheckOverlap(T.ArrayClass, T.ArrayClass);
- CheckDisjoint(T.ObjectClass, T.ArrayClass);
-
- CheckOverlap(T.SmiConstant, T.Smi);
- CheckOverlap(T.SmiConstant, T.Signed32);
- CheckOverlap(T.SmiConstant, T.Number);
- CheckDisjoint(T.SmiConstant, T.Double);
- CheckOverlap(T.ObjectConstant1, T.Object);
- CheckOverlap(T.ObjectConstant2, T.Object);
- CheckOverlap(T.ArrayConstant1, T.Object);
- CheckOverlap(T.ArrayConstant1, T.Array);
- CheckOverlap(T.ArrayConstant1, T.ArrayConstant2);
- CheckOverlap(T.ObjectConstant1, T.ObjectConstant1);
- CheckDisjoint(T.ObjectConstant1, T.ObjectConstant2);
- CheckDisjoint(T.ObjectConstant1, T.ArrayConstant1);
-
- CheckDisjoint(T.ObjectConstant1, T.ObjectClass);
- CheckDisjoint(T.ObjectConstant2, T.ObjectClass);
- CheckDisjoint(T.ObjectConstant1, T.ArrayClass);
- CheckDisjoint(T.ObjectConstant2, T.ArrayClass);
- CheckDisjoint(T.ArrayConstant1, T.ObjectClass);
+ CheckOverlap(T.Any, T.Any, T.Semantic);
+ CheckOverlap(T.Object, T.Object, T.Semantic);
+
+ CheckOverlap(T.Oddball, T.Any, T.Semantic);
+ CheckOverlap(T.Boolean, T.Oddball, T.Semantic);
+ CheckOverlap(T.Null, T.Oddball, T.Semantic);
+ CheckOverlap(T.Undefined, T.Oddball, T.Semantic);
+ CheckDisjoint(T.Boolean, T.Null, T.Semantic);
+ CheckDisjoint(T.Undefined, T.Null, T.Semantic);
+ CheckDisjoint(T.Boolean, T.Undefined, T.Semantic);
+
+ CheckOverlap(T.Number, T.Any, T.Semantic);
+ CheckOverlap(T.SignedSmall, T.Number, T.Semantic);
+ CheckOverlap(T.Float, T.Number, T.Semantic);
+ CheckDisjoint(T.Signed32, T.Float, T.Semantic);
+
+ CheckOverlap(T.Name, T.Any, T.Semantic);
+ CheckOverlap(T.UniqueName, T.Any, T.Semantic);
+ CheckOverlap(T.UniqueName, T.Name, T.Semantic);
+ CheckOverlap(T.String, T.Name, T.Semantic);
+ CheckOverlap(T.InternalizedString, T.String, T.Semantic);
+ CheckOverlap(T.InternalizedString, T.UniqueName, T.Semantic);
+ CheckOverlap(T.InternalizedString, T.Name, T.Semantic);
+ CheckOverlap(T.Symbol, T.UniqueName, T.Semantic);
+ CheckOverlap(T.Symbol, T.Name, T.Semantic);
+ CheckOverlap(T.String, T.UniqueName, T.Semantic);
+ CheckDisjoint(T.String, T.Symbol, T.Semantic);
+ CheckDisjoint(T.InternalizedString, T.Symbol, T.Semantic);
+
+ CheckOverlap(T.Receiver, T.Any, T.Semantic);
+ CheckOverlap(T.Object, T.Any, T.Semantic);
+ CheckOverlap(T.Object, T.Receiver, T.Semantic);
+ CheckOverlap(T.Array, T.Object, T.Semantic);
+ CheckOverlap(T.Function, T.Object, T.Semantic);
+ CheckOverlap(T.Proxy, T.Receiver, T.Semantic);
+ CheckDisjoint(T.Object, T.Proxy, T.Semantic);
+ CheckDisjoint(T.Array, T.Function, T.Semantic);
+
+ CheckOverlap(T.ObjectClass, T.Any, T.Semantic);
+ CheckOverlap(T.ObjectConstant1, T.Any, T.Semantic);
+
+ CheckOverlap(T.ObjectClass, T.Object, T.Semantic);
+ CheckOverlap(T.ArrayClass, T.Object, T.Semantic);
+ CheckOverlap(T.ObjectClass, T.ObjectClass, T.Semantic);
+ CheckOverlap(T.ArrayClass, T.ArrayClass, T.Semantic);
+ CheckDisjoint(T.ObjectClass, T.ArrayClass, T.Semantic);
+
+ CheckOverlap(T.SmiConstant, T.SignedSmall, T.Semantic);
+ CheckOverlap(T.SmiConstant, T.Signed32, T.Semantic);
+ CheckOverlap(T.SmiConstant, T.Number, T.Semantic);
+ CheckDisjoint(T.SmiConstant, T.Float, T.Semantic);
+ CheckOverlap(T.ObjectConstant1, T.Object, T.Semantic);
+ CheckOverlap(T.ObjectConstant2, T.Object, T.Semantic);
+ CheckOverlap(T.ArrayConstant1, T.Object, T.Semantic);
+ CheckOverlap(T.ArrayConstant1, T.Array, T.Semantic);
+ CheckOverlap(T.ArrayConstant1, T.ArrayConstant2, T.Semantic);
+ CheckOverlap(T.ObjectConstant1, T.ObjectConstant1, T.Semantic);
+ CheckDisjoint(T.ObjectConstant1, T.ObjectConstant2, T.Semantic);
+ CheckDisjoint(T.ObjectConstant1, T.ArrayConstant1, T.Semantic);
+
+ CheckDisjoint(T.ObjectConstant1, T.ObjectClass, T.Semantic);
+ CheckDisjoint(T.ObjectConstant2, T.ObjectClass, T.Semantic);
+ CheckDisjoint(T.ObjectConstant1, T.ArrayClass, T.Semantic);
+ CheckDisjoint(T.ObjectConstant2, T.ArrayClass, T.Semantic);
+ CheckDisjoint(T.ArrayConstant1, T.ObjectClass, T.Semantic);
}
void Union() {
CheckSub(T.ArrayClass, T.Union(T.ObjectClass, T.ArrayClass));
CheckSub(T.Union(T.ObjectClass, T.ArrayClass), T.Object);
CheckUnordered(T.Union(T.ObjectClass, T.ArrayClass), T.Array);
- CheckOverlap(T.Union(T.ObjectClass, T.ArrayClass), T.Array);
- CheckDisjoint(T.Union(T.ObjectClass, T.ArrayClass), T.Number);
+ CheckOverlap(T.Union(T.ObjectClass, T.ArrayClass), T.Array, T.Semantic);
+ CheckDisjoint(T.Union(T.ObjectClass, T.ArrayClass), T.Number, T.Semantic);
// Constant-constant
CHECK(this->IsConstant(T.Union(T.ObjectConstant1, T.ObjectConstant1)));
CheckUnordered(
T.Union(T.ObjectConstant1, T.ObjectConstant2), T.ObjectClass);
CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayConstant1), T.Array);
- CheckOverlap(T.Union(T.ObjectConstant1, T.ArrayConstant1), T.Array);
CheckOverlap(
- T.Union(T.ObjectConstant1, T.ArrayConstant1), T.ArrayConstant2);
- CheckDisjoint(T.Union(T.ObjectConstant1, T.ArrayConstant1), T.Number);
- CheckDisjoint(T.Union(T.ObjectConstant1, T.ArrayConstant1), T.ObjectClass);
+ T.Union(T.ObjectConstant1, T.ArrayConstant1), T.Array, T.Semantic);
+ CheckOverlap(
+ T.Union(T.ObjectConstant1, T.ArrayConstant1), T.ArrayConstant2,
+ T.Semantic);
+ CheckDisjoint(
+ T.Union(T.ObjectConstant1, T.ArrayConstant1), T.Number, T.Semantic);
+ CheckDisjoint(
+ T.Union(T.ObjectConstant1, T.ArrayConstant1), T.ObjectClass,
+ T.Semantic);
// Bitset-class
CHECK(this->IsBitset(T.Union(T.ObjectClass, T.Object)));
CheckEqual(T.Union(T.ObjectClass, T.Object), T.Object);
CheckSub(T.None, T.Union(T.ObjectClass, T.Number));
CheckSub(T.Union(T.ObjectClass, T.Number), T.Any);
- CheckSub(T.Union(T.ObjectClass, T.Smi), T.Union(T.Object, T.Number));
+ CheckSub(
+ T.Union(T.ObjectClass, T.SignedSmall), T.Union(T.Object, T.Number));
CheckSub(T.Union(T.ObjectClass, T.Array), T.Object);
CheckUnordered(T.Union(T.ObjectClass, T.String), T.Array);
- CheckOverlap(T.Union(T.ObjectClass, T.String), T.Object);
- CheckDisjoint(T.Union(T.ObjectClass, T.String), T.Number);
+ CheckOverlap(T.Union(T.ObjectClass, T.String), T.Object, T.Semantic);
+ CheckDisjoint(T.Union(T.ObjectClass, T.String), T.Number, T.Semantic);
// Bitset-constant
CHECK(this->IsBitset(T.Union(T.SmiConstant, T.Number)));
T.Union(T.ObjectConstant1, T.Signed32), T.Union(T.Object, T.Number));
CheckSub(T.Union(T.ObjectConstant1, T.Array), T.Object);
CheckUnordered(T.Union(T.ObjectConstant1, T.String), T.Array);
- CheckOverlap(T.Union(T.ObjectConstant1, T.String), T.Object);
- CheckDisjoint(T.Union(T.ObjectConstant1, T.String), T.Number);
+ CheckOverlap(T.Union(T.ObjectConstant1, T.String), T.Object, T.Semantic);
+ CheckDisjoint(T.Union(T.ObjectConstant1, T.String), T.Number, T.Semantic);
CheckEqual(T.Union(T.Signed32, T.Signed32Constant), T.Signed32);
// Class-constant
CheckSub(
T.Union(T.ObjectConstant1, T.ArrayClass), T.Union(T.Array, T.Object));
CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayClass), T.ArrayConstant1);
- CheckDisjoint(T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectConstant2);
- CheckDisjoint(T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectClass);
+ CheckDisjoint(
+ T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectConstant2,
+ T.Semantic);
+ CheckDisjoint(
+ T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectClass, T.Semantic);
// Bitset-union
CHECK(this->IsBitset(
T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number),
T.Union(T.ObjectConstant1, T.Union(T.Number, T.ArrayClass)));
CheckSub(
- T.Double,
+ T.Float,
T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number));
CheckSub(
T.ObjectConstant1,
- T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Double));
+ T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Float));
CheckSub(
T.None,
- T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Double));
+ T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Float));
CheckSub(
- T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Double),
+ T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Float),
T.Any);
CheckSub(
- T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Double),
+ T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Float),
T.Union(T.ObjectConstant1, T.Union(T.Number, T.ArrayClass)));
// Class-union
T.Union(T.ObjectConstant1, T.ObjectConstant2),
T.ArrayConstant1));
CheckEqual(
- T.Union(T.Union(T.Number, T.ArrayClass), T.Union(T.Smi, T.Array)),
+ T.Union(
+ T.Union(T.Number, T.ArrayClass),
+ T.Union(T.SignedSmall, T.Array)),
T.Union(T.Number, T.Array));
}
CHECK(this->IsBitset(T.Intersect(T.Any, T.None)));
CheckEqual(T.Intersect(T.None, T.Number), T.None);
- CheckEqual(T.Intersect(T.Object, T.Proxy), T.None);
+ CheckSub(T.Intersect(T.Object, T.Proxy), T.Representation);
CheckEqual(T.Intersect(T.Name, T.String), T.Intersect(T.String, T.Name));
CheckEqual(T.Intersect(T.UniqueName, T.String), T.InternalizedString);
CHECK(this->IsBitset(T.Intersect(T.ObjectClass, T.Number)));
CheckEqual(T.Intersect(T.ObjectClass, T.Object), T.ObjectClass);
- CheckEqual(T.Intersect(T.ObjectClass, T.Array), T.None);
- CheckEqual(T.Intersect(T.ObjectClass, T.Number), T.None);
+ CheckSub(T.Intersect(T.ObjectClass, T.Array), T.Representation);
+ CheckSub(T.Intersect(T.ObjectClass, T.Number), T.Representation);
// Bitset-constant
- CHECK(this->IsBitset(T.Intersect(T.Smi, T.Number)));
+ CHECK(this->IsBitset(T.Intersect(T.SignedSmall, T.Number)));
CHECK(this->IsConstant(T.Intersect(T.SmiConstant, T.Number)));
CHECK(this->IsConstant(T.Intersect(T.ObjectConstant1, T.Object)));
- CheckEqual(T.Intersect(T.Smi, T.Number), T.Smi);
+ CheckEqual(T.Intersect(T.SignedSmall, T.Number), T.SignedSmall);
CheckEqual(T.Intersect(T.SmiConstant, T.Number), T.SmiConstant);
CheckEqual(T.Intersect(T.ObjectConstant1, T.Object), T.ObjectConstant1);
CheckEqual(
T.Intersect(
T.Union(T.Number, T.ArrayClass),
- T.Union(T.Smi, T.Array)),
- T.Union(T.Smi, T.ArrayClass));
+ T.Union(T.SignedSmall, T.Array)),
+ T.Union(T.SignedSmall, T.ArrayClass));
CheckEqual(
T.Intersect(
T.Union(T.Number, T.ObjectClass),