Delete StructArray and Shape
[hiphop-php.git] / hphp / runtime / vm / jit / type-specialization-inl.h
blob4617a4a246a43cd7779fa166f07fc8b4e87296ed
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-2016 Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 namespace HPHP { namespace jit {
18 ///////////////////////////////////////////////////////////////////////////////
20 inline SpecKind operator|(SpecKind l, SpecKind r) {
21 return static_cast<SpecKind>(
22 static_cast<uint8_t>(l) | static_cast<uint8_t>(r));
25 inline SpecKind operator&(SpecKind l, SpecKind r) {
26 return static_cast<SpecKind>(
27 static_cast<uint8_t>(l) & static_cast<uint8_t>(r));
30 inline SpecKind& operator|=(SpecKind& l, SpecKind r) {
31 return l = l | r;
34 ///////////////////////////////////////////////////////////////////////////////
36 inline TypeSpec::TypeSpec()
37 : m_kind(SpecKind::None)
40 inline TypeSpec::TypeSpec(ArraySpec arrSpec, ClassSpec clsSpec)
41 : m_kind(SpecKind::None)
42 , m_arrSpec(arrSpec)
43 , m_clsSpec(clsSpec)
45 if (arrSpec != ArraySpec::Bottom) m_kind |= SpecKind::Array;
46 if (clsSpec != ClassSpec::Bottom) m_kind |= SpecKind::Class;
49 inline SpecKind TypeSpec::kind() const {
50 return m_kind;
53 inline ArraySpec TypeSpec::arrSpec() const {
54 return m_arrSpec;
57 inline ClassSpec TypeSpec::clsSpec() const {
58 return m_clsSpec;
61 inline bool TypeSpec::operator==(const TypeSpec& rhs) const {
62 auto const& lhs = *this;
63 return lhs.arrSpec() == rhs.arrSpec() &&
64 lhs.clsSpec() == rhs.clsSpec();
67 inline bool TypeSpec::operator!=(const TypeSpec& rhs) const {
68 return !(*this == rhs);
71 inline bool TypeSpec::operator<=(const TypeSpec& rhs) const {
72 auto const& lhs = *this;
73 return lhs.arrSpec() <= rhs.arrSpec() &&
74 lhs.clsSpec() <= rhs.clsSpec();
77 inline bool TypeSpec::operator>=(const TypeSpec& rhs) const {
78 return rhs <= *this;
81 inline TypeSpec TypeSpec::operator|(const TypeSpec& rhs) const {
82 auto const& lhs = *this;
83 return TypeSpec(lhs.arrSpec() | rhs.arrSpec(),
84 lhs.clsSpec() | rhs.clsSpec());
87 inline TypeSpec TypeSpec::operator&(const TypeSpec& rhs) const {
88 auto const& lhs = *this;
89 return TypeSpec(lhs.arrSpec() & rhs.arrSpec(),
90 lhs.clsSpec() & rhs.clsSpec());
93 inline TypeSpec TypeSpec::operator-(const TypeSpec& rhs) const {
94 auto const& lhs = *this;
95 return TypeSpec(lhs.arrSpec() - rhs.arrSpec(),
96 lhs.clsSpec() - rhs.clsSpec());
99 ///////////////////////////////////////////////////////////////////////////////
101 #define IMPLEMENT_SPEC_OPERS(Spec) \
102 inline uintptr_t Spec::bits() const { \
103 return m_bits; \
105 inline Spec::operator bool() const { \
106 return *this != Top && *this != Spec::Bottom; \
108 inline bool Spec::operator==(const Spec& rhs) const { \
109 return m_bits == rhs.m_bits; \
111 inline bool Spec::operator!=(const Spec& rhs) const { \
112 return !(*this == rhs); \
114 inline bool Spec::operator>=(const Spec& rhs) const { \
115 return rhs <= *this; \
117 inline bool Spec::operator<(const Spec& rhs) const { \
118 return *this <= rhs && *this != rhs; \
120 inline bool Spec::operator>(const Spec& rhs) const { \
121 return *this >= rhs && *this != rhs; \
123 inline Spec Spec::operator-(const Spec& rhs) const { \
124 return *this <= rhs ? Bottom : *this; \
127 ///////////////////////////////////////////////////////////////////////////////
128 // ArraySpec.
130 constexpr inline ArraySpec::ArraySpec()
131 : m_sort(IsTop)
132 , m_kind(ArrayData::ArrayKind{})
133 , m_ptr(0)
136 inline ArraySpec::ArraySpec(ArraySpec::BottomTag)
137 : m_sort(IsBottom)
138 , m_kind(ArrayData::ArrayKind{})
139 , m_ptr(0)
142 inline ArraySpec::ArraySpec(ArrayData::ArrayKind kind)
143 : m_sort(HasKind)
144 , m_kind(kind)
145 , m_ptr(0)
148 inline ArraySpec::ArraySpec(const RepoAuthType::Array* arrTy)
149 : m_sort(HasType)
150 , m_kind(ArrayData::ArrayKind{})
151 , m_ptr(reinterpret_cast<uintptr_t>(arrTy))
154 inline ArraySpec::ArraySpec(ArrayData::ArrayKind kind,
155 const RepoAuthType::Array* arrTy)
156 : m_sort(HasKind | HasType)
157 , m_kind(kind)
158 , m_ptr(reinterpret_cast<uintptr_t>(arrTy))
161 inline folly::Optional<ArrayData::ArrayKind> ArraySpec::kind() const {
162 auto kind = static_cast<ArrayData::ArrayKind>(m_kind);
163 return (m_sort & HasKind) ? folly::make_optional(kind) : folly::none;
166 inline const RepoAuthType::Array* ArraySpec::type() const {
167 return (m_sort & HasType)
168 ? reinterpret_cast<const RepoAuthType::Array*>(m_ptr)
169 : nullptr;
172 IMPLEMENT_SPEC_OPERS(ArraySpec)
174 ///////////////////////////////////////////////////////////////////////////////
176 inline ArraySpec::SortOf operator|(ArraySpec::SortOf l, ArraySpec::SortOf r) {
177 return static_cast<ArraySpec::SortOf>(
178 static_cast<uint8_t>(l) | static_cast<uint8_t>(r));
181 inline ArraySpec::SortOf operator&(ArraySpec::SortOf l, ArraySpec::SortOf r) {
182 return static_cast<ArraySpec::SortOf>(
183 static_cast<uint8_t>(l) & static_cast<uint8_t>(r));
186 ///////////////////////////////////////////////////////////////////////////////
187 // ClassSpec.
189 constexpr inline ClassSpec::ClassSpec()
190 : m_sort(IsTop)
191 , m_ptr(0)
194 inline ClassSpec::ClassSpec(ClassSpec::BottomTag)
195 : m_sort(IsBottom)
196 , m_ptr(0)
199 inline ClassSpec::ClassSpec(const Class* cls, ClassSpec::SubTag)
200 : m_sort(IsSub)
201 , m_ptr(reinterpret_cast<uintptr_t>(cls))
204 inline ClassSpec::ClassSpec(const Class* cls, ClassSpec::ExactTag)
205 : m_sort(IsExact)
206 , m_ptr(reinterpret_cast<uintptr_t>(cls))
209 inline bool ClassSpec::exact() const {
210 return m_sort == IsExact;
213 inline const Class* ClassSpec::cls() const {
214 return (m_sort == IsSub || m_sort == IsExact)
215 ? reinterpret_cast<const Class*>(m_ptr)
216 : nullptr;
219 inline const Class* ClassSpec::exactCls() const {
220 return (m_sort == IsExact)
221 ? reinterpret_cast<const Class*>(m_ptr)
222 : nullptr;
225 IMPLEMENT_SPEC_OPERS(ClassSpec)
227 ///////////////////////////////////////////////////////////////////////////////
229 #undef IMPLEMENT_SPEC_OPERS