Rename null_variant to uninit_variant
[hiphop-php.git] / hphp / runtime / vm / jit / type.h
blob90093e5688f9aab0771f7aea9592fdf3f09ca289
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 #ifndef incl_HPHP_JIT_TYPE_H_
18 #define incl_HPHP_JIT_TYPE_H_
20 #include "hphp/runtime/base/array-data.h"
21 #include "hphp/runtime/base/datatype.h"
22 #include "hphp/runtime/base/rds.h"
23 #include "hphp/runtime/base/repo-auth-type.h"
24 #include "hphp/runtime/vm/jit/types.h"
25 #include "hphp/runtime/vm/jit/type-specialization.h"
27 #include <folly/Optional.h>
29 #include <cstdint>
30 #include <type_traits>
32 namespace HPHP {
33 ///////////////////////////////////////////////////////////////////////////////
35 struct ArrayData;
36 struct Class;
37 struct Func;
38 struct StringData;
39 struct TypedValue;
41 namespace jit {
42 ///////////////////////////////////////////////////////////////////////////////
45 * The Ptr enum is a lattice that represents the "pointerness" of a type:
46 * whether it's a pointer at all, and what kind of location it may point to.
48 * We have a pointer kind for each of the major segregated locations in which
49 * php values can live (eval stack, frame slots, properties, etc...). For most
50 * of the primitive kinds, we have a predefined union of the kind and "inside a
51 * Ref", so PtrToRStkGen is exactly the same as PtrTo{Ref|Stk}Gen. These
52 * classify PtrTo* types into some categories that cannot possibly alias,
53 * without any smarter analysis needed to prove it. There is also a union for
54 * the various locations things can point after a fully generic member
55 * operation (see Memb below).
57 * The reason we have the category "Ref|Foo" for each of these Foos is that it
58 * is very common to need to do a generic unbox on some value if you have no
59 * type information. For example:
61 * t1 = LdPropAddr ...
62 * t2 = UnboxPtr t1
64 * At this point, t2 is a pointer into either an object property or a inner
65 * RefData, which will be a PtrToRPropCell, which means it still can't alias,
66 * for example, a PtrToStkGen or a PtrToGblGen (although it could generally
67 * alias a PtrToRGblGen because both could be inside the same RefData.). Note
68 * that PtrToRFooGen is just shorthand for PtrTo{Ref|Foo}Gen.
70 * Memb is a number of different locations that result from the more generic
71 * types of member operations: Prop, Elem, MIS, MMisc, and Other. MMisc
72 * contains something living in a collection instance or object's dynamic
73 * property array. Other contains init_null_variant, uninit_variant, or the
74 * lvalBlackHole.
76 * ClsInit is a pointer to class property initializer data. These can never be
77 * refs, so we don't have a RClsInit type.
79 * ClsCns is a pointer to class constant values in RDS.
81 * Ptr is a supertype of all Ptr types, Foo is a subtype of RFoo, and Ref is a
82 * subtype of RFoo. NotPtr is unrelated to all other types. The hierarchy looks
83 * something like this:
85 * Ptr NotPtr
86 * |
87 * +-------------------+----+--------+-------+
88 * | | | |
89 * RMemb | ClsInit ClsCns
90 * | |
91 * +------+---------+ |
92 * | | | |
93 * | | | |
94 * | | | |
95 * | | +----+-----+ +--------+----- ... etc
96 * | | | | | | |
97 * | Memb RMIS RProp RElem RFrame RStk
98 * | | / | / | /| | \ | \
99 * | +--+-+/---|/+ |/ | | Frame | Stk
100 * | | / / | / | | |
101 * | | /| /| | /| | | |
102 * | | / | / | | / | | | |
103 * | MIS Prop | Elem| | | |
104 * | | | | | |
105 * +-------------+--+--+--+--------+---------+
107 * Ref
109 * Note: if you add a new pointer type, you very likely need to update
110 * pointee() in memory-effects.cpp for it to remain correct.
114 #define PTR_R(f, name, bits, ...) \
115 f(name, bits, __VA_ARGS__) \
116 f(R##name, (bits) | Ref, __VA_ARGS__)
118 #define PTR_NO_R(f, name, bits, ...) \
119 f(name, bits, __VA_ARGS__)
122 * Types that can never be refs directly call f; types that can call r with f
123 * as an argument. Callers of PTR_TYPES may control whether the Ref cases are
124 * actually expanded by passing PTR_R or PTR_NO_R for the r argument. Any
125 * arguments passed beyond f and r will be forwarded to f.
127 #define PTR_PRIMITIVE(f, r, ...) \
128 f(Ref, 1U << 0, __VA_ARGS__) \
129 f(ClsInit, 1U << 1, __VA_ARGS__) \
130 f(ClsCns, 1U << 2, __VA_ARGS__) \
131 r(f, Frame, 1U << 3, __VA_ARGS__) \
132 r(f, Stk, 1U << 4, __VA_ARGS__) \
133 r(f, Gbl, 1U << 5, __VA_ARGS__) \
134 r(f, Prop, 1U << 6, __VA_ARGS__) \
135 r(f, Elem, 1U << 7, __VA_ARGS__) \
136 r(f, SProp, 1U << 8, __VA_ARGS__) \
137 r(f, MIS, 1U << 9, __VA_ARGS__) \
138 r(f, MMisc, 1U << 10, __VA_ARGS__) \
139 r(f, Other, 1U << 11, __VA_ARGS__) \
140 /* NotPtr, 1U << 12, declared below */
142 #define PTR_TYPES(f, r, ...) \
143 PTR_PRIMITIVE(f, r, __VA_ARGS__) \
144 r(f, Memb, Prop | Elem | MIS | MMisc | Other, __VA_ARGS__)
146 enum class Ptr : uint16_t {
148 * The Ptr kinds here are kept out of PTR_TYPES to avoid generating names
149 * like TPtrToNotPtrGen or TPtrToPtrGen. Note that those types do exist, just
150 * with less ridiculous names: TGen and TPtrToGen, respectively.
152 Bottom = 0,
153 Top = 0x1fffU, // Keep this in sync with the number of bits used in
154 // PTR_PRIMITIVE, to keep pretty-printing cleaner.
155 NotPtr = 1U << 12,
156 Ptr = Top & ~NotPtr,
158 #define PTRT(name, bits, ...) name = (bits),
159 PTR_TYPES(PTRT, PTR_R)
160 #undef PTRT
163 using ptr_t = std::underlying_type<Ptr>::type;
164 constexpr auto kPtrRefBit = static_cast<ptr_t>(Ptr::Ref);
166 constexpr Ptr operator|(Ptr a, Ptr b) {
167 return static_cast<Ptr>(static_cast<ptr_t>(a) | static_cast<ptr_t>(b));
169 constexpr Ptr operator&(Ptr a, Ptr b) {
170 return static_cast<Ptr>(static_cast<ptr_t>(a) & static_cast<ptr_t>(b));
172 constexpr Ptr operator-(Ptr a, Ptr b) {
173 return static_cast<Ptr>(static_cast<ptr_t>(a) & ~static_cast<ptr_t>(b));
175 bool operator<=(Ptr a, Ptr b) = delete;
176 bool operator>=(Ptr, Ptr) = delete;
177 bool operator<(Ptr, Ptr) = delete;
178 bool operator>(Ptr, Ptr) = delete;
179 constexpr bool ptrSubsetOf(Ptr a, Ptr b) {
180 return (a & b) == a;
183 ///////////////////////////////////////////////////////////////////////////////
185 #define IRTP_FROM_PTR(ptr, ptr_bits, name) \
186 IRTP(PtrTo##ptr##name, ptr, k##name) \
188 #define IRT_BOXES_AND_PTRS(name, bits) \
189 IRT(name, (bits)) \
190 IRT(Boxed##name, (bits) << kBoxShift) \
191 IRTP(PtrTo##name, Ptr, k##name) \
192 IRTP(PtrToBoxed##name, Ptr, kBoxed##name) \
193 PTR_TYPES(IRTP_FROM_PTR, PTR_R, name) \
194 PTR_TYPES(IRTP_FROM_PTR, PTR_NO_R, Boxed##name)
196 #define IRT_PHP(c) \
197 c(Uninit, 1ULL << 0) \
198 c(InitNull, 1ULL << 1) \
199 c(Bool, 1ULL << 2) \
200 c(Int, 1ULL << 3) \
201 c(Dbl, 1ULL << 4) \
202 c(StaticStr, 1ULL << 5) \
203 c(UncountedStr, 1ULL << 6) \
204 c(CountedStr, 1ULL << 7) \
205 c(StaticArr, 1ULL << 8) \
206 c(UncountedArr, 1ULL << 9) \
207 c(CountedArr, 1ULL << 10) \
208 c(StaticVec, 1ULL << 11) \
209 c(UncountedVec, 1ULL << 12) \
210 c(CountedVec, 1ULL << 13) \
211 c(StaticDict, 1ULL << 14) \
212 c(UncountedDict, 1ULL << 15) \
213 c(CountedDict, 1ULL << 16) \
214 c(StaticKeyset, 1ULL << 17) \
215 c(UncountedKeyset, 1ULL << 18) \
216 c(CountedKeyset, 1ULL << 19) \
217 c(Obj, 1ULL << 20) \
218 c(Res, 1ULL << 21)
219 // Boxed*: 22-44
222 * This list should be in non-decreasing order of specificity.
224 #define IRT_PHP_UNIONS(c) \
225 c(Null, kUninit|kInitNull) \
226 c(PersistentStr, kStaticStr|kUncountedStr) \
227 c(Str, kPersistentStr|kCountedStr) \
228 c(PersistentArr, kStaticArr|kUncountedArr) \
229 c(Arr, kPersistentArr|kCountedArr) \
230 c(PersistentVec, kStaticVec|kUncountedVec) \
231 c(Vec, kPersistentVec|kCountedVec) \
232 c(PersistentDict, kStaticDict|kUncountedDict) \
233 c(Dict, kPersistentDict|kCountedDict) \
234 c(PersistentKeyset, kStaticKeyset|kUncountedKeyset) \
235 c(Keyset, kPersistentKeyset|kCountedKeyset) \
236 c(PersistentArrLike, kPersistentArr|kPersistentVec|kPersistentDict|kPersistentKeyset) \
237 c(ArrLike, kArr|kVec|kDict|kKeyset) \
238 c(NullableObj, kObj|kInitNull|kUninit) \
239 c(Persistent, kPersistentStr|kPersistentArrLike) \
240 c(UncountedInit, kInitNull|kBool|kInt|kDbl|kPersistent) \
241 c(Uncounted, kUninit|kUncountedInit) \
242 c(InitCell, kUncountedInit|kStr|kArrLike|kObj|kRes) \
243 c(Cell, kUninit|kInitCell)
245 #define IRT_RUNTIME \
246 IRT(Cls, 1ULL << 45) \
247 IRT(Func, 1ULL << 46) \
248 IRT(VarEnv, 1ULL << 47) \
249 IRT(NamedEntity, 1ULL << 48) \
250 IRT(Cctx, 1ULL << 49) /* Class* with the lowest bit set, */ \
251 /* as stored in ActRec.m_cls field */ \
252 IRT(RetAddr, 1ULL << 50) /* Return address */ \
253 IRT(StkPtr, 1ULL << 51) /* Stack pointer */ \
254 IRT(FramePtr, 1ULL << 52) /* Frame pointer */ \
255 IRT(TCA, 1ULL << 53) \
256 IRT(ABC, 1ULL << 54) /* AsioBlockableChain */ \
257 IRT(RDSHandle, 1ULL << 55) /* rds::Handle */ \
258 IRT(Nullptr, 1ULL << 56) \
259 /* bits 57-64 are unused */
262 * Gen, Counted, Init, PtrToGen, etc... are here instead of IRT_PHP_UNIONS
263 * because boxing them (e.g., BoxedGen, PtrToBoxedGen) would yield nonsense
264 * types.
266 #define IRT_SPECIAL \
267 /* Bottom and Top use IRTP to specify a custom Ptr kind */ \
268 IRTP(Bottom, Bottom, kBottom) \
269 IRTP(Top, Top, kTop) \
270 IRT(Ctx, kObj|kCctx) \
271 IRTP(AnyObj, Top, kAnyObj) \
272 IRTP(AnyArr, Top, kAnyArr) \
273 IRTP(AnyVec, Top, kAnyVec) \
274 IRTP(AnyDict, Top, kAnyDict) \
275 IRTP(AnyKeyset, Top, kAnyKeyset) \
276 IRTP(AnyArrLike, Top, kAnyArrLike) \
277 IRT(Counted, kCountedStr|kCountedArr|kCountedVec|kCountedDict|kCountedKeyset|kObj|kRes|kBoxedCell) \
278 IRTP(PtrToCounted, Ptr, kCounted) \
279 IRT(Gen, kCell|kBoxedCell) \
280 IRT(InitGen, kGen & ~kUninit) \
281 IRT(StkElem, kGen|kCls) \
282 IRTP(PtrToGen, Ptr, kGen) \
283 IRTP(PtrToInitGen, Ptr, kInitGen) \
284 PTR_TYPES(IRTP_FROM_PTR, PTR_R, Gen) \
285 PTR_TYPES(IRTP_FROM_PTR, PTR_R, InitGen)
288 * All types that represent a non-union type.
290 #define IRT_PRIMITIVE IRT_PHP(IRT_BOXES_AND_PTRS) IRT_RUNTIME
293 * All types.
295 #define IR_TYPES \
296 IRT_PHP(IRT_BOXES_AND_PTRS) \
297 IRT_PHP_UNIONS(IRT_BOXES_AND_PTRS) \
298 IRT_RUNTIME \
299 IRT_SPECIAL
301 ///////////////////////////////////////////////////////////////////////////////
303 struct ConstCctx {
304 static ConstCctx cctx(const Class* c) {
305 return ConstCctx { reinterpret_cast<uintptr_t>(c) | 0x1 };
308 const Class* cls() const {
309 return reinterpret_cast<const Class*>(m_val & ~0x1);
312 uintptr_t m_val;
315 ///////////////////////////////////////////////////////////////////////////////
318 * Type is used to represent the types of values in the jit. Every Type
319 * represents a set of types, with TTop being a superset of all Types and
320 * TBottom being a subset of all Types. The elements forming these sets of
321 * types come from the types of PHP-visible values (Str, Obj, Int, ...) and
322 * runtime-internal types (Func, TCA, ...).
324 * Types can be constructed from the predefined constants or by composing
325 * existing Types in various ways. Unions, intersections, and subtractions are
326 * all supported, though for implementation-specific reasons certain
327 * combinations of specialized types cannot be represented. A type is
328 * considered specialized if it refers to a specific Class or a
329 * ArrayData::ArrayKind. As an example, if A and B are unrelated Classes,
330 * Obj<A> | Obj<B> is impossible to represent. However, if B is a subclass of
331 * A, Obj<A> | Obj<B> == Obj<B>, which can be represented as a Type.
333 struct Type {
334 private:
335 using bits_t = uint64_t;
336 static constexpr size_t kBoxShift = 22;
338 public:
339 enum Bits : bits_t {
340 kBottom = 0ULL,
341 kTop = 0xffffffffffffffffULL,
343 #define IRT(name, bits) k##name = (bits),
344 #define IRTP(name, ptr, bits)
345 IR_TYPES
346 #undef IRT
347 #undef IRTP
349 kAnyArr = kArr | kBoxedArr,
350 kAnyVec = kVec | kBoxedVec,
351 kAnyDict = kDict | kBoxedDict,
352 kAnyKeyset = kKeyset | kBoxedKeyset,
353 kAnyArrLike = kAnyArr | kAnyVec | kAnyDict | kAnyKeyset,
354 kArrSpecBits = kAnyArr,
355 kAnyObj = kObj | kBoxedObj,
356 kClsSpecBits = kAnyObj | kCls,
359 /////////////////////////////////////////////////////////////////////////////
360 // Basic methods.
362 public:
364 * Default bottom constructor.
366 Type();
369 * Construct from a predefined set of bits & pointer kind.
371 constexpr Type(bits_t bits, Ptr kind);
374 * Hash the Type as a bitfield.
376 size_t hash() const;
379 * Stringify the Type.
381 * constValString: @requires: hasConstVal() ||
382 * subtypeOfAny(Uninit, InitNull, Nullptr)
384 std::string toString() const;
385 std::string constValString() const;
386 static std::string debugString(Type t);
389 /////////////////////////////////////////////////////////////////////////////
390 // DataType.
393 * Construct from a DataType.
395 explicit Type(DataType outer, DataType inner = KindOfUninit);
398 * Return true iff there exists a DataType in the range [KindOfUninit,
399 * KindOfRef] that represents a non-strict supertype of this type.
401 * @requires: *this <= StkElem
403 bool isKnownDataType() const;
406 * Return the most specific DataType that is a supertype of this Type.
408 * @requires: isKnownDataType()
410 DataType toDataType() const;
413 /////////////////////////////////////////////////////////////////////////////
414 // Comparisons. [const]
417 * Return true if this is exactly equal to `rhs'.
419 * Be careful---you probably mean `<='.
421 bool operator==(Type rhs) const;
422 bool operator!=(Type rhs) const;
425 * Does this represent a subset (or superset) of `t2'?
427 * All operators are implemented in terms of operator==() and operator<=().
429 bool operator<=(Type rhs) const;
430 bool operator>=(Type rhs) const;
431 bool operator<(Type rhs) const;
432 bool operator>(Type rhs) const;
435 * Is this a non-strict subtype of any among a variadic list of Types?
437 template<typename... Types>
438 bool subtypeOfAny(Type t2, Types... ts) const;
439 bool subtypeOfAny() const;
442 * Return true if this has nontrivial intersection with `t2'.
444 bool maybe(Type t2) const;
447 /////////////////////////////////////////////////////////////////////////////
448 // Combinators.
451 * Set operations: union, intersection, and difference.
453 * These operations may all return larger types than the "true" union,
454 * intersection, or difference. (They must be conservative in that direction
455 * for types that are too hard for us to represent, or we could generate
456 * incorrect code by assuming certain possible values are impossible.)
458 * Note: operator| and operator& guarantee commutativity; operator- guarantees
459 * (a - b) <= a.
461 Type operator|(Type other) const;
462 Type& operator|=(Type other) { return *this = *this | other; }
464 Type operator&(Type other) const;
465 Type& operator&=(Type other) { return *this = *this & other; }
467 Type operator-(Type other) const;
468 Type& operator-=(Type other) { return *this = *this - other; }
471 /////////////////////////////////////////////////////////////////////////////
472 // Is-a methods. [const]
475 * Is this a union type?
477 * Note that this is the plain old set definition of union, so TStr,
478 * TArr, and TNull will all return true.
480 bool isUnion() const;
483 * Does this require a register to hold a DataType at runtime?
485 bool needsReg() const;
488 * Return true if this corresponds to a type that is passed by (value/
489 * reference) in C++.
491 bool isSimpleType() const;
492 bool isReferenceType() const;
495 /////////////////////////////////////////////////////////////////////////////
496 // Constant type creation. [const/static]
499 * Return a const copy of `ret' with constant value `val'.
501 template<typename T>
502 static Type cns(T val, Type ret);
505 * Return a const type corresponding to `val'.
507 * @returns: cns(val, forConst(val))
509 template<typename T>
510 static Type cns(T val);
513 * @returns: TNullptr
515 static Type cns(std::nullptr_t);
518 * Return a const type for `tv'.
520 static Type cns(const TypedValue& tv);
523 * If this represents a constant value, return the most specific strict
524 * supertype of this we can represent, else return *this.
526 * In most cases this just erases the constant value:
527 * Int<4> -> Int
528 * Dbl<2.5> -> Dbl
530 * Arrays are special since they can be both constant and specialized, so
531 * keep the array's kind in the resulting type.
533 Type dropConstVal() const;
536 /////////////////////////////////////////////////////////////////////////////
537 // Constant introspection. [const]
540 * Does this Type have a constant value? If true, we can call xxVal().
542 * Note: Bottom is a type with no value, and Uninit/InitNull/Nullptr are
543 * considered types with a single unique value, so this function returns false
544 * for those types. You may want to explicitly check for them as needed.
547 bool hasConstVal() const;
550 * @return hasConstVal() && *this <= t.
552 bool hasConstVal(Type t) const;
555 * Does this Type represent the constant val `val'?
557 * @returns: hasConstVal(cns(val))
559 template<typename T>
560 bool hasConstVal(T val) const;
563 * Return the const value for a const Type as a uint64_t.
565 * @requires: hasConstVal()
567 uint64_t rawVal() const;
570 * Return the const value for a const Type.
572 * @requires: hasConstVal(Type::T)
574 bool boolVal() const;
575 int64_t intVal() const;
576 double dblVal() const;
577 const StringData* strVal() const;
578 const ArrayData* arrVal() const;
579 const ArrayData* vecVal() const;
580 const ArrayData* dictVal() const;
581 const ArrayData* keysetVal() const;
582 const HPHP::Func* funcVal() const;
583 const Class* clsVal() const;
584 ConstCctx cctxVal() const;
585 rds::Handle rdsHandleVal() const;
586 jit::TCA tcaVal() const;
589 /////////////////////////////////////////////////////////////////////////////
590 // Specialized type creation. [const/static]
593 * Return a specialized TArr.
595 static Type Array(ArrayData::ArrayKind kind);
596 static Type Array(const RepoAuthType::Array* rat);
599 * Return a specialized TStaticArr.
601 static Type StaticArray(ArrayData::ArrayKind kind);
602 static Type StaticArray(const RepoAuthType::Array* rat);
605 * Return a specialized TObj.
607 static Type SubObj(const Class* cls);
608 static Type ExactObj(const Class* cls);
610 static Type ExactCls(const Class* cls);
611 static Type SubCls(const Class* cls);
614 * Return a copy of this Type with the specialization dropped.
616 * @returns: Type(m_bits)
618 Type unspecialize() const;
621 /////////////////////////////////////////////////////////////////////////////
622 // Specialization introspection. [const]
625 * Does this Type have a specialization?
627 bool isSpecialized() const;
630 * Whether this type can meaningfully specialize along `kind'.
632 * For example, a Type only supports SpecKind::Class if its bits intersect
633 * nontrivially with kAnyObj.
635 bool supports(SpecKind kind) const;
638 * Return the corresponding type specialization.
640 * If the Type is able to support the specialization (i.e., supports()
641 * returns true for the corresponding SpecKind), but no specialization is
642 * present, Spec::Top will be returned.
644 * If supports() would return false for the corresponding SpecKind,
645 * Spec::Bottom is returned.
647 * The Spec objects cast (explicitly) to true iff they are neither Spec::Top
648 * nor Spec::Bottom, so these functions also answer the question, "Is this
649 * Type nontrivially specialized along the respective kind?"
651 ArraySpec arrSpec() const;
652 ClassSpec clsSpec() const;
655 * Return a discriminated TypeSpec for this Type's specialization.
657 TypeSpec spec() const;
660 /////////////////////////////////////////////////////////////////////////////
661 // Inner types. [const]
664 * Box or unbox a Type.
666 * The box() and inner() methods are inverses---they (respectively) take the
667 * the {Cell, BoxedCell} bits of the Type and coerce them into the
668 * {BoxedCell, Cell} sides of the lattice, replacing whatever was there
669 * before; e.g.,
671 * box(Int|BoxedDbl) -> BoxedInt
672 * inner(BoxedInt|Dbl) -> Int
674 * Meanwhile, unbox() is like inner(), but rather than replacing the Cell
675 * component of the Type, it unions it with the shifted BoxedCell bits, e.g.,
677 * unbox(BoxedInt|Dbl) -> Int|Dbl
679 * @requires:
680 * box: *this <= Cell
681 * !maybe(Uninit) || *this == Cell
682 * inner: *this <= BoxedCell
683 * unbox: *this <= Gen
685 Type box() const;
686 Type inner() const;
687 Type unbox() const;
690 * Get a pointer to, or dereference, a Type.
692 * @requires:
693 * ptr: *this <= Gen && kind <= Ptr::Ptr
694 * deref: *this <= PtrToGen
695 * derefIfPtr: *this <= (Gen | PtrToGen)
697 Type ptr(Ptr kind) const;
698 Type deref() const;
699 Type derefIfPtr() const;
702 * Return a Type stripped of boxing and pointerness.
704 Type strip() const;
707 * Return the pointer category of a Type.
709 Ptr ptrKind() const;
712 /////////////////////////////////////////////////////////////////////////////
713 // Internal methods.
715 private:
717 * Internal constructors.
719 Type(bits_t bits, Ptr kind, uintptr_t extra);
720 Type(Type t, ArraySpec arraySpec);
721 Type(Type t, ClassSpec classSpec);
724 * Bit-pack an `outer' and an `inner' DataType for a Type.
726 static bits_t bitsFromDataType(DataType outer, DataType inner);
729 * Check invariants and return false if the type is malformed.
731 bool checkValid() const;
734 * Return a version of *this with the given specialization. If TypeSpec
735 * contains both kinds of specialization or *this supports both types of
736 * specialization, the resulting type will not be specialized at all. Any
737 * constant value in *this will be dropped if the specialization is
738 * applied. *this must support any specializations present in the given
739 * TypeSpec.
741 Type specialize(TypeSpec) const;
744 * Do the given bits support a specific kind of specialization?
746 static bool supports(bits_t, SpecKind kind);
748 /////////////////////////////////////////////////////////////////////////////
749 // Data members.
751 private:
752 union {
753 bits_t m_bits;
754 Bits m_typedBits;
756 Ptr m_ptrKind;
757 bool m_hasConstVal;
759 union {
760 uintptr_t m_extra;
762 // Constant values. Validity determined by m_hasConstVal and m_bits.
763 bool m_boolVal;
764 int64_t m_intVal;
765 double m_dblVal;
766 const StringData* m_strVal;
767 const ArrayData* m_arrVal;
768 const ArrayData* m_vecVal;
769 const ArrayData* m_dictVal;
770 const ArrayData* m_keysetVal;
771 const HPHP::Func* m_funcVal;
772 const Class* m_clsVal;
773 ConstCctx m_cctxVal;
774 jit::TCA m_tcaVal;
775 rds::Handle m_rdsHandleVal;
776 TypedValue* m_ptrVal;
778 // Specializations for object classes and arrays.
779 ClassSpec m_clsSpec;
780 ArraySpec m_arrSpec;
784 using OptType = folly::Optional<Type>;
786 /////////////////////////////////////////////////////////////////////////////
789 * Return the most refined Type that can be used to represent the type of a
790 * live TypedValue or a RepoAuthType.
792 Type typeFromTV(const TypedValue* tv, const Class* ctx);
793 Type typeFromRAT(RepoAuthType ty, const Class* ctx);
796 ///////////////////////////////////////////////////////////////////////////////
799 * Return the boxed version of the input type, taking into account PHP
800 * semantics and subtle implementation details.
802 Type boxType(Type);
805 * Return the dest type for a LdRef with the given typeParam.
807 * @requires: typeParam <= TCell
809 Type ldRefReturn(Type typeParam);
812 * Returns the type that a value may have if it had type `srcType' and failed a
813 * CheckType with `typeParam'. Not all typeParams for CheckTypes are precise,
814 * so the return value may even be `srcType' itself in some situations.
816 Type negativeCheckType(Type typeParam, Type srcType);
819 * Returns the least specific supertype of `t' that maintains the properties
820 * required by `cat'.
822 Type relaxType(Type t, DataTypeCategory cat);
825 * Returns the smallest supertype of ty that we can reasonably guard on. Used
826 * for checking inner ref cells and locals in pesudomains.
828 Type relaxToGuardable(Type ty);
830 ///////////////////////////////////////////////////////////////////////////////
834 ///////////////////////////////////////////////////////////////////////////////
836 namespace std {
837 template<> struct hash<HPHP::jit::Type> {
838 size_t operator()(HPHP::jit::Type t) const { return t.hash(); }
842 ///////////////////////////////////////////////////////////////////////////////
844 #define incl_HPHP_JIT_TYPE_INL_H_
845 #include "hphp/runtime/vm/jit/type-inl.h"
846 #undef incl_HPHP_JIT_TYPE_INL_H_
848 #endif