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