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
9using namespace v8::internal;
10
11
12static const HType kTypes[] = {
13  #define DECLARE_TYPE(Name, mask) HType::Name(),
14  HTYPE_LIST(DECLARE_TYPE)
15  #undef DECLARE_TYPE
16};
17
18static const int kNumberOfTypes = sizeof(kTypes) / sizeof(kTypes[0]);
19
20
21TEST(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
30TEST(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
43TEST(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
70TEST(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
83TEST(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
98TEST(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
115TEST(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
126TEST(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
142TEST(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
157TEST(HTypeJSObject) {
158  CHECK(HType::JSArray().IsJSObject());
159}
160
161
162TEST(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