2 +----------------------------------------------------------------------+
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>
30 #include <type_traits>
33 ///////////////////////////////////////////////////////////////////////////////
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:
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
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:
87 * +-------------------+----+--------+-------+
89 * RMemb | ClsInit ClsCns
91 * +------+---------+ |
95 * | | +----+-----+ +--------+----- ... etc
97 * | Memb RMIS RProp RElem RFrame RStk
98 * | | / | / | /| | \ | \
99 * | +--+-+/---|/+ |/ | | Frame | Stk
101 * | | /| /| | /| | | |
102 * | | / | / | | / | | | |
103 * | MIS Prop | Elem| | | |
105 * +-------------+--+--+--+--------+---------+
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.
153 Top
= 0x1fffU
, // Keep this in sync with the number of bits used in
154 // PTR_PRIMITIVE, to keep pretty-printing cleaner.
158 #define PTRT(name, bits, ...) name = (bits),
159 PTR_TYPES(PTRT
, PTR_R
)
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
) {
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) \
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)
197 c(Uninit, 1ULL << 0) \
198 c(InitNull, 1ULL << 1) \
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) \
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
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
296 IRT_PHP(IRT_BOXES_AND_PTRS) \
297 IRT_PHP_UNIONS(IRT_BOXES_AND_PTRS) \
301 ///////////////////////////////////////////////////////////////////////////////
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);
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.
335 using bits_t
= uint64_t;
336 static constexpr size_t kBoxShift
= 22;
341 kTop
= 0xffffffffffffffffULL
,
343 #define IRT(name, bits) k##name = (bits),
344 #define IRTP(name, ptr, bits)
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 /////////////////////////////////////////////////////////////////////////////
364 * Default bottom constructor.
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.
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 /////////////////////////////////////////////////////////////////////////////
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 /////////////////////////////////////////////////////////////////////////////
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
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/
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'.
502 static Type
cns(T val
, Type ret
);
505 * Return a const type corresponding to `val'.
507 * @returns: cns(val, forConst(val))
510 static Type
cns(T val
);
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:
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))
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
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
681 * !maybe(Uninit) || *this == Cell
682 * inner: *this <= BoxedCell
683 * unbox: *this <= Gen
690 * Get a pointer to, or dereference, a Type.
693 * ptr: *this <= Gen && kind <= Ptr::Ptr
694 * deref: *this <= PtrToGen
695 * derefIfPtr: *this <= (Gen | PtrToGen)
697 Type
ptr(Ptr kind
) const;
699 Type
derefIfPtr() const;
702 * Return a Type stripped of boxing and pointerness.
707 * Return the pointer category of a Type.
712 /////////////////////////////////////////////////////////////////////////////
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
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 /////////////////////////////////////////////////////////////////////////////
762 // Constant values. Validity determined by m_hasConstVal and m_bits.
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
;
775 rds::Handle m_rdsHandleVal
;
776 TypedValue
* m_ptrVal
;
778 // Specializations for object classes and arrays.
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.
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
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 ///////////////////////////////////////////////////////////////////////////////
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_