| // Copyright 2014 the V8 project authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "src/crankshaft/hydrogen-types.h" |
| |
| #include "test/cctest/cctest.h" |
| |
| using namespace v8::internal; |
| |
| static const HType kTypes[] = { |
| #define DECLARE_TYPE(Name, mask) HType::Name(), |
| HTYPE_LIST(DECLARE_TYPE) |
| #undef DECLARE_TYPE |
| }; |
| |
| static const int kNumberOfTypes = sizeof(kTypes) / sizeof(kTypes[0]); |
| |
| |
| TEST(HTypeDistinct) { |
| for (int i = 0; i < kNumberOfTypes; ++i) { |
| for (int j = 0; j < kNumberOfTypes; ++j) { |
| CHECK(i == j || !kTypes[i].Equals(kTypes[j])); |
| } |
| } |
| } |
| |
| |
| TEST(HTypeReflexivity) { |
| // Reflexivity of = |
| for (int i = 0; i < kNumberOfTypes; ++i) { |
| CHECK(kTypes[i].Equals(kTypes[i])); |
| } |
| |
| // Reflexivity of < |
| for (int i = 0; i < kNumberOfTypes; ++i) { |
| CHECK(kTypes[i].IsSubtypeOf(kTypes[i])); |
| } |
| } |
| |
| |
| TEST(HTypeTransitivity) { |
| // Transitivity of = |
| for (int i = 0; i < kNumberOfTypes; ++i) { |
| for (int j = 0; j < kNumberOfTypes; ++j) { |
| for (int k = 0; k < kNumberOfTypes; ++k) { |
| HType ti = kTypes[i]; |
| HType tj = kTypes[j]; |
| HType tk = kTypes[k]; |
| CHECK(!ti.Equals(tj) || !tj.Equals(tk) || ti.Equals(tk)); |
| } |
| } |
| } |
| |
| // Transitivity of < |
| for (int i = 0; i < kNumberOfTypes; ++i) { |
| for (int j = 0; j < kNumberOfTypes; ++j) { |
| for (int k = 0; k < kNumberOfTypes; ++k) { |
| HType ti = kTypes[i]; |
| HType tj = kTypes[j]; |
| HType tk = kTypes[k]; |
| CHECK(!ti.IsSubtypeOf(tj) || !tj.IsSubtypeOf(tk) || ti.IsSubtypeOf(tk)); |
| } |
| } |
| } |
| } |
| |
| |
| TEST(HTypeCombine) { |
| // T < T /\ T' and T' < T /\ T' for all T,T' |
| for (int i = 0; i < kNumberOfTypes; ++i) { |
| for (int j = 0; j < kNumberOfTypes; ++j) { |
| HType ti = kTypes[i]; |
| HType tj = kTypes[j]; |
| CHECK(ti.IsSubtypeOf(ti.Combine(tj))); |
| CHECK(tj.IsSubtypeOf(ti.Combine(tj))); |
| } |
| } |
| } |
| |
| |
| TEST(HTypeAny) { |
| // T < Any for all T |
| for (int i = 0; i < kNumberOfTypes; ++i) { |
| HType ti = kTypes[i]; |
| CHECK(ti.IsAny()); |
| } |
| |
| // Any < T implies T = Any for all T |
| for (int i = 0; i < kNumberOfTypes; ++i) { |
| HType ti = kTypes[i]; |
| CHECK(!HType::Any().IsSubtypeOf(ti) || HType::Any().Equals(ti)); |
| } |
| } |
| |
| |
| TEST(HTypeTagged) { |
| // T < Tagged for all T \ {Any} |
| for (int i = 0; i < kNumberOfTypes; ++i) { |
| HType ti = kTypes[i]; |
| CHECK(ti.IsTagged() || HType::Any().Equals(ti)); |
| } |
| |
| // Tagged < T implies T = Tagged or T = Any |
| for (int i = 0; i < kNumberOfTypes; ++i) { |
| HType ti = kTypes[i]; |
| CHECK(!HType::Tagged().IsSubtypeOf(ti) || |
| HType::Tagged().Equals(ti) || |
| HType::Any().Equals(ti)); |
| } |
| } |
| |
| |
| TEST(HTypeSmi) { |
| // T < Smi implies T = None or T = Smi for all T |
| for (int i = 0; i < kNumberOfTypes; ++i) { |
| HType ti = kTypes[i]; |
| CHECK(!ti.IsSmi() || |
| ti.Equals(HType::Smi()) || |
| ti.Equals(HType::None())); |
| } |
| } |
| |
| |
| TEST(HTypeHeapObject) { |
| CHECK(!HType::TaggedPrimitive().IsHeapObject()); |
| CHECK(!HType::TaggedNumber().IsHeapObject()); |
| CHECK(!HType::Smi().IsHeapObject()); |
| CHECK(HType::HeapObject().IsHeapObject()); |
| CHECK(HType::HeapPrimitive().IsHeapObject()); |
| CHECK(HType::Null().IsHeapObject()); |
| CHECK(HType::HeapNumber().IsHeapObject()); |
| CHECK(HType::String().IsHeapObject()); |
| CHECK(HType::Boolean().IsHeapObject()); |
| CHECK(HType::Undefined().IsHeapObject()); |
| CHECK(HType::JSObject().IsHeapObject()); |
| CHECK(HType::JSArray().IsHeapObject()); |
| } |
| |
| |
| TEST(HTypePrimitive) { |
| CHECK(HType::TaggedNumber().IsTaggedPrimitive()); |
| CHECK(HType::Smi().IsTaggedPrimitive()); |
| CHECK(!HType::HeapObject().IsTaggedPrimitive()); |
| CHECK(HType::HeapPrimitive().IsTaggedPrimitive()); |
| CHECK(HType::Null().IsHeapPrimitive()); |
| CHECK(HType::HeapNumber().IsHeapPrimitive()); |
| CHECK(HType::String().IsHeapPrimitive()); |
| CHECK(HType::Boolean().IsHeapPrimitive()); |
| CHECK(HType::Undefined().IsHeapPrimitive()); |
| CHECK(!HType::JSObject().IsTaggedPrimitive()); |
| CHECK(!HType::JSArray().IsTaggedPrimitive()); |
| } |
| |
| |
| TEST(HTypeJSObject) { |
| CHECK(HType::JSArray().IsJSObject()); |
| } |
| |
| |
| TEST(HTypeNone) { |
| // None < T for all T |
| for (int i = 0; i < kNumberOfTypes; ++i) { |
| HType ti = kTypes[i]; |
| CHECK(HType::None().IsSubtypeOf(ti)); |
| } |
| } |