1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "src/hydrogen-types.h"
6 
7 #include "test/cctest/cctest.h"
8 
9 using namespace v8::internal;
10 
11 
12 static const HType kTypes[] = {
13   #define DECLARE_TYPE(Name, mask) HType::Name(),
14   HTYPE_LIST(DECLARE_TYPE)
15   #undef DECLARE_TYPE
16 };
17 
18 static const int kNumberOfTypes = sizeof(kTypes) / sizeof(kTypes[0]);
19 
20 
TEST(HTypeDistinct)21 TEST(HTypeDistinct) {
22   for (int i = 0; i < kNumberOfTypes; ++i) {
23     for (int j = 0; j < kNumberOfTypes; ++j) {
24       CHECK(i == j || !kTypes[i].Equals(kTypes[j]));
25     }
26   }
27 }
28 
29 
TEST(HTypeReflexivity)30 TEST(HTypeReflexivity) {
31   // Reflexivity of =
32   for (int i = 0; i < kNumberOfTypes; ++i) {
33     CHECK(kTypes[i].Equals(kTypes[i]));
34   }
35 
36   // Reflexivity of <
37   for (int i = 0; i < kNumberOfTypes; ++i) {
38     CHECK(kTypes[i].IsSubtypeOf(kTypes[i]));
39   }
40 }
41 
42 
TEST(HTypeTransitivity)43 TEST(HTypeTransitivity) {
44   // Transitivity of =
45   for (int i = 0; i < kNumberOfTypes; ++i) {
46     for (int j = 0; j < kNumberOfTypes; ++j) {
47       for (int k = 0; k < kNumberOfTypes; ++k) {
48         HType ti = kTypes[i];
49         HType tj = kTypes[j];
50         HType tk = kTypes[k];
51         CHECK(!ti.Equals(tj) || !tj.Equals(tk) || ti.Equals(tk));
52       }
53     }
54   }
55 
56   // Transitivity of <
57   for (int i = 0; i < kNumberOfTypes; ++i) {
58     for (int j = 0; j < kNumberOfTypes; ++j) {
59       for (int k = 0; k < kNumberOfTypes; ++k) {
60         HType ti = kTypes[i];
61         HType tj = kTypes[j];
62         HType tk = kTypes[k];
63         CHECK(!ti.IsSubtypeOf(tj) || !tj.IsSubtypeOf(tk) || ti.IsSubtypeOf(tk));
64       }
65     }
66   }
67 }
68 
69 
TEST(HTypeCombine)70 TEST(HTypeCombine) {
71   // T < T /\ T' and T' < T /\ T' for all T,T'
72   for (int i = 0; i < kNumberOfTypes; ++i) {
73     for (int j = 0; j < kNumberOfTypes; ++j) {
74       HType ti = kTypes[i];
75       HType tj = kTypes[j];
76       CHECK(ti.IsSubtypeOf(ti.Combine(tj)));
77       CHECK(tj.IsSubtypeOf(ti.Combine(tj)));
78     }
79   }
80 }
81 
82 
TEST(HTypeAny)83 TEST(HTypeAny) {
84   // T < Any for all T
85   for (int i = 0; i < kNumberOfTypes; ++i) {
86     HType ti = kTypes[i];
87     CHECK(ti.IsAny());
88   }
89 
90   // Any < T implies T = Any for all T
91   for (int i = 0; i < kNumberOfTypes; ++i) {
92     HType ti = kTypes[i];
93     CHECK(!HType::Any().IsSubtypeOf(ti) || HType::Any().Equals(ti));
94   }
95 }
96 
97 
TEST(HTypeTagged)98 TEST(HTypeTagged) {
99   // T < Tagged for all T \ {Any}
100   for (int i = 0; i < kNumberOfTypes; ++i) {
101     HType ti = kTypes[i];
102     CHECK(ti.IsTagged() || HType::Any().Equals(ti));
103   }
104 
105   // Tagged < T implies T = Tagged or T = Any
106   for (int i = 0; i < kNumberOfTypes; ++i) {
107     HType ti = kTypes[i];
108     CHECK(!HType::Tagged().IsSubtypeOf(ti) ||
109           HType::Tagged().Equals(ti) ||
110           HType::Any().Equals(ti));
111   }
112 }
113 
114 
TEST(HTypeSmi)115 TEST(HTypeSmi) {
116   // T < Smi implies T = None or T = Smi for all T
117   for (int i = 0; i < kNumberOfTypes; ++i) {
118     HType ti = kTypes[i];
119     CHECK(!ti.IsSmi() ||
120           ti.Equals(HType::Smi()) ||
121           ti.Equals(HType::None()));
122   }
123 }
124 
125 
TEST(HTypeHeapObject)126 TEST(HTypeHeapObject) {
127   CHECK(!HType::TaggedPrimitive().IsHeapObject());
128   CHECK(!HType::TaggedNumber().IsHeapObject());
129   CHECK(!HType::Smi().IsHeapObject());
130   CHECK(HType::HeapObject().IsHeapObject());
131   CHECK(HType::HeapPrimitive().IsHeapObject());
132   CHECK(HType::Null().IsHeapObject());
133   CHECK(HType::HeapNumber().IsHeapObject());
134   CHECK(HType::String().IsHeapObject());
135   CHECK(HType::Boolean().IsHeapObject());
136   CHECK(HType::Undefined().IsHeapObject());
137   CHECK(HType::JSObject().IsHeapObject());
138   CHECK(HType::JSArray().IsHeapObject());
139 }
140 
141 
TEST(HTypePrimitive)142 TEST(HTypePrimitive) {
143   CHECK(HType::TaggedNumber().IsTaggedPrimitive());
144   CHECK(HType::Smi().IsTaggedPrimitive());
145   CHECK(!HType::HeapObject().IsTaggedPrimitive());
146   CHECK(HType::HeapPrimitive().IsTaggedPrimitive());
147   CHECK(HType::Null().IsHeapPrimitive());
148   CHECK(HType::HeapNumber().IsHeapPrimitive());
149   CHECK(HType::String().IsHeapPrimitive());
150   CHECK(HType::Boolean().IsHeapPrimitive());
151   CHECK(HType::Undefined().IsHeapPrimitive());
152   CHECK(!HType::JSObject().IsTaggedPrimitive());
153   CHECK(!HType::JSArray().IsTaggedPrimitive());
154 }
155 
156 
TEST(HTypeJSObject)157 TEST(HTypeJSObject) {
158   CHECK(HType::JSArray().IsJSObject());
159 }
160 
161 
TEST(HTypeNone)162 TEST(HTypeNone) {
163   // None < T for all T
164   for (int i = 0; i < kNumberOfTypes; ++i) {
165     HType ti = kTypes[i];
166     CHECK(HType::None().IsSubtypeOf(ti));
167   }
168 }
169