Clear the container before decoding for inplace adapter
[hiphop-php.git] / hphp / hhbbc / index.h
blobe0fad79102714d2de687b2e17ccdad396e92c2fc
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present 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 +----------------------------------------------------------------------+
16 #pragma once
18 #include <memory>
19 #include <tuple>
20 #include <vector>
21 #include <map>
22 #include <exception>
24 #include <boost/variant.hpp>
25 #include <tbb/concurrent_hash_map.h>
27 #include <folly/synchronization/Baton.h>
28 #include <folly/Hash.h>
30 #include "hphp/util/compact-vector.h"
31 #include "hphp/util/either.h"
32 #include "hphp/util/tiny-vector.h"
33 #include "hphp/util/tribool.h"
35 #include "hphp/runtime/base/repo-auth-type.h"
37 #include "hphp/runtime/vm/coeffects.h"
38 #include "hphp/runtime/vm/type-constraint.h"
40 #include "hphp/hhbbc/hhbbc.h"
41 #include "hphp/hhbbc/misc.h"
43 namespace HPHP::HHBBC {
45 //////////////////////////////////////////////////////////////////////
47 struct Type;
48 struct Index;
49 struct PublicSPropMutations;
50 struct FuncAnalysisResult;
51 struct Context;
52 struct ContextHash;
53 struct CallContext;
54 struct PropertiesInfo;
55 struct MethodsInfo;
57 struct TypeStructureResolution;
59 struct DCls;
61 extern const Type TCell;
63 namespace php {
64 struct Class;
65 struct Prop;
66 struct Const;
67 struct Func;
68 struct Unit;
69 struct Program;
70 struct TypeAlias;
73 //////////////////////////////////////////////////////////////////////
76 * This module contains functions for building and querying an Index
77 * of data relating to "resolved" versions of the names in of a
78 * php::Program. It also records dependencies so it is possible to
79 * tell which parts of the program may be interested in new inferred
80 * information about other parts of the program.
82 * The main entry point here is the Index class. The Index is built
83 * after parse time, and then analysis can query it for information.
86 //////////////////////////////////////////////////////////////////////
88 enum class Dep : uintptr_t {
89 /* This dependency should trigger when the return type changes */
90 ReturnTy = (1u << 0),
91 /* This dependency should trigger when a DefCns is resolved */
92 ConstVal = (1u << 1),
93 /* This dependency should trigger when a class constant is resolved */
94 ClsConst = (1u << 2),
95 /* This dependency should trigger when the bad initial prop value bit for a
96 * class changes */
97 PropBadInitialValues = (1u << 3),
98 /* This dependency should trigger when a public static property changes */
99 PublicSProp = (1u << 4),
100 /* This dependency means that we refused to do inline analysis on
101 * this function due to inline analysis depth. The dependency will
102 * trigger if the target function becomes effect-free, or gets a
103 * literal return value.
105 InlineDepthLimit = (1u << 5),
109 * A DependencyContext encodes enough of the context to record a dependency - a
110 * php::Func, if we're doing private property analysis and its a suitable class,
111 * a php::Class, or a public static property.
114 enum class DependencyContextType : uint16_t {
115 Func,
116 Class,
117 Prop,
118 FuncFamily
121 using DependencyContext = CompactTaggedPtr<const void, DependencyContextType>;
123 struct DependencyContextEquals {
124 bool operator()(const DependencyContext& a,
125 const DependencyContext& b) const {
126 return a.getOpaque() == b.getOpaque();
130 struct DependencyContextHash {
131 size_t operator()(const DependencyContext& d) const {
132 return pointer_hash<void>{}(reinterpret_cast<void*>(d.getOpaque()));
136 struct DependencyContextHashCompare : DependencyContextHash {
137 bool equal(const DependencyContext& a, const DependencyContext& b) const {
138 return a.getOpaque() == b.getOpaque();
140 size_t hash(const DependencyContext& d) const { return (*this)(d); }
143 using DependencyContextSet = hphp_fast_set<DependencyContext,
144 DependencyContextHash,
145 DependencyContextEquals>;
147 std::string show(Context);
150 * State of properties on a class. Map from property name to its
151 * Type.
153 template <typename T = Type> // NB: The template param here is to
154 // break a cyclic dependency on Type.
155 struct PropStateElem {
156 T ty;
157 const TypeConstraint* tc = nullptr;
158 Attr attrs;
159 bool everModified;
161 bool operator==(const PropStateElem<T>& o) const {
162 return
163 ty == o.ty &&
164 tc == o.tc &&
165 attrs == o.attrs &&
166 everModified == o.everModified;
169 using PropState = std::map<LSString,PropStateElem<>>;
172 * The result of Index::lookup_static
174 template <typename T = Type> // NB: The template parameter is here to
175 // break a cyclic dependency on Type.
176 struct PropLookupResult {
177 T ty; // The best known type of the property (TBottom if not found)
178 SString name; // The statically known name of the string, if any
179 TriBool found; // If the property was found
180 TriBool isConst; // If the property is AttrConst
181 TriBool readOnly; // If the property is AttrIsReadonly
182 TriBool lateInit; // If the property is AttrLateInit
183 TriBool internal; // If the property is Internal
184 bool classInitMightRaise; // If class initialization during the
185 // property access can raise (unlike the
186 // others, this is only no or maybe).
189 template <typename T>
190 inline PropLookupResult<T>& operator|=(PropLookupResult<T>& a,
191 const PropLookupResult<T>& b) {
192 assertx(a.name == b.name);
193 a.ty |= b.ty;
194 a.found |= b.found;
195 a.isConst |= b.isConst;
196 a.readOnly |= b.readOnly;
197 a.lateInit |= b.lateInit;
198 a.internal |= b.internal;
199 a.classInitMightRaise |= b.classInitMightRaise;
200 return a;
203 std::string show(const PropLookupResult<Type>&);
206 * The result of Index::merge_static_type
208 template <typename T = Type> // NB: The template parameter is here to
209 // break a cyclic dependency on Type
210 struct PropMergeResult {
211 T adjusted; // The merged type, potentially adjusted according to
212 // the prop's type-constraint (it's the subtype of the
213 // merged type that would succeed).
214 TriBool throws; // Whether the mutation this merge represents
215 // can throw.
218 template <typename T>
219 inline PropMergeResult<T>& operator|=(PropMergeResult<T>& a,
220 const PropMergeResult<T>& b) {
221 a.adjusted |= b.adjusted;
222 a.throws |= b.throws;
223 return a;
226 std::string show(const PropMergeResult<Type>&);
229 * The result of Index::lookup_class_constant
231 template <typename T = Type> // NB: The template parameter is here to
232 // break a cyclic dependency on Type
233 struct ClsConstLookupResult {
234 T ty; // The best known type of the constant (might not be a
235 // scalar).
236 TriBool found; // If the constant was found
237 bool mightThrow; // If accessing the constant can throw
240 template <typename T>
241 inline ClsConstLookupResult<T>& operator|=(ClsConstLookupResult<T>& a,
242 const ClsConstLookupResult<T>& b) {
243 a.ty |= b.ty;
244 a.found |= b.found;
245 a.mightThrow |= b.mightThrow;
246 return a;
249 std::string show(const ClsConstLookupResult<Type>&);
252 * The result of Index::lookup_class_type_constant
254 template <typename T = TypeStructureResolution>
255 struct ClsTypeConstLookupResult {
256 T resolution; // The result from resolving the type-structure
257 TriBool found; // If the constant was found
258 TriBool abstract; // If the constant was abstract (this only applies
259 // to the subset which wasn't found).
262 template <typename T>
263 inline ClsTypeConstLookupResult<T>& operator|=(
264 ClsTypeConstLookupResult<T>& a,
265 const ClsTypeConstLookupResult<T>& b) {
266 a.resolution |= b.resolution;
267 if (a.found == TriBool::Yes) {
268 a.abstract = b.abstract;
269 } else if (b.found != TriBool::Yes) {
270 a.abstract |= b.abstract;
272 a.found |= b.found;
273 return a;
276 std::string show(const ClsTypeConstLookupResult<TypeStructureResolution>&);
278 //////////////////////////////////////////////////////////////////////
280 // private types
281 struct ClassInfo;
283 //////////////////////////////////////////////////////////////////////
286 * References to "resolved" entities with information in the index are
287 * in the res:: namespace.
289 * These represent handles to program entities that may have variable
290 * amounts of information. For example, we may know the name of a
291 * class in a res::Class, but do not know for sure which php::Class
292 * struct is actually associated with it.
294 namespace res {
297 * A resolved runtime Class, for a particular php::Class.
299 * Provides various lookup tables that allow querying the Class'
300 * information.
302 struct Class {
304 * Returns whether two (exact) classes are definitely same at
305 * runtime. This ignores all complications due to non-regular
306 * classes and is usually not what you want to use.
308 bool same(const Class& o) const;
311 * Returns true if this class is a subtype of 'o'. That is, every
312 * subclass of 'this' (including 'this' itself) is a subclass of
313 * 'o'. For the exact variant, 'this' is considered to be exact
314 * (that is, exactly that class). For the sub variant, 'this' could
315 * also be a subclass. This distinction only matters for non-regular
316 * classes. 'o' is considered to be a subclass except for
317 * exactSubtypeOfExact. This is needed since two exact classes, even
318 * if the same, may not be a sub-type of one another if
319 * nonRegularL/nonRegularR differ.
321 * Classes can have implementations/subclasses which aren't
322 * "regular" classes (interfaces/traits/abstract/etc). Whether these
323 * will be considered as part of the check (on either side) is
324 * context dependent and specified by nonRegularL and nonRegularR.
326 bool exactSubtypeOf(const Class& o, bool nonRegularL, bool nonRegularR) const;
327 bool exactSubtypeOfExact(
328 const Class& o, bool nonRegularL, bool nonRegularR
329 ) const;
330 bool subSubtypeOf(const Class& o, bool nonRegularL, bool nonRegularR) const;
333 * Returns false if this class has no subclasses in common with
334 * 'o'. This is equivalent to saying that their intersection is
335 * empty. For the exact variant, 'this' is considered to be exactly
336 * that class (no sub-classes). For the sub variant, 'this' might be
337 * that class, or any subclass of that class.
339 * Since couldBe is symmetric, this covers all of the cases. 'o' is
340 * considered to be a subclass, except for exactCouldBeExact. This
341 * is needed since two exact classes, even if the same, may not have
342 * anything in common if nonRegularL/nonRegularR differ.
344 * Classes can have implementations/subclasses which aren't
345 * "regular" classes (interfaces/traits/abstract/etc). Whether these
346 * will be considered as part of the check (on either side) is
347 * context dependent and specified by nonRegularL and nonRegularR.
349 bool exactCouldBe(const Class& o, bool nonRegularL, bool nonRegularR) const;
350 bool exactCouldBeExact(
351 const Class& o, bool nonRegularL, bool nonRegularR
352 ) const;
353 bool subCouldBe(const Class& o, bool nonRegularL, bool nonRegularR) const;
356 * Returns the name of this class. Non-null guarantee.
358 SString name() const;
361 * Returns whether this class is a final class as determined by
362 * static analysis. The first variant considers all classes, while
363 * the second variant only considers potentially overriding regular
364 * classes (this distinction is important if you already have an
365 * instance of the class, as abstract classes cannot be
366 * instantiated).
368 * NB: Traits never can be overridden and will always return false
369 * (their subclass list reflects users which the trait will be
370 * flattened into at runtime).
372 * When returning false the class is guaranteed to be final. When
373 * returning true the system cannot tell though the class may still
374 * be final.
376 bool couldBeOverridden() const;
377 bool couldBeOverriddenByRegular() const;
380 * Returns whether this class might be a regular/non-regular class
381 * at runtime. For resolved classes this check is precise, but for
382 * unresolved classes this will always conservatively return
383 * true. This only checks the class itself and says nothing about
384 * any potential subclasses of this.
386 bool mightBeRegular() const;
387 bool mightBeNonRegular() const;
390 * Whether this class (or its subtypes) might be a non-regular
391 * class. For resolved classes this check is precise, but for
392 * unresolved classes this will always conservatively return true.
394 bool mightContainNonRegular() const;
397 * Return the best class equivalent to this, but with any
398 * non-regular classes removed. By equivalent, we mean the most
399 * specific representable class which contains all of the same
400 * regular subclasses that the original did. If std::nullopt is
401 * returned, this class contains no regular classes (and therefore
402 * the result is a Bottom). The returned classes may be the original
403 * class, and for interfaces and abstract classes, the result may
404 * not be an interface or abstract class.
406 Optional<res::Class> withoutNonRegular() const;
409 * Whether this class (or its subtypes) could possibly have have
410 * a magic toBoolean() method.
412 bool couldHaveMagicBool() const;
415 * Whether this class could possibly have a sub-class that is
416 * mocked, including itself.
418 bool couldHaveMockedSubClass() const;
421 * Whether this class could possibly be mocked.
423 bool couldBeMocked() const;
426 * Whether this class could have reified generics
428 bool couldHaveReifiedGenerics() const;
431 * Whether this class must have reified generics
433 bool mustHaveReifiedGenerics() const;
436 * Whether this class could have a reified parent
438 bool couldHaveReifiedParent() const;
441 * Whether this class must have a reified parent
443 bool mustHaveReifiedParent() const;
446 * Returns whether this resolved class might distinguish being constructed
447 * dynamically versus being constructed normally (IE, might raise a notice).
449 bool mightCareAboutDynConstructs() const;
452 * Whether this class (or clases derived from it) could have const props.
454 bool couldHaveConstProp() const;
455 bool subCouldHaveConstProp() const;
458 * Returns the res::Class for this Class's parent if there is one,
459 * or nullptr.
461 Optional<Class> parent() const;
464 * Returns true if we have a ClassInfo for this Class.
466 bool resolved() const {
467 return val.right() != nullptr;
471 * Returns the php::Class for this Class if there is one, or
472 * nullptr.
474 const php::Class* cls() const;
477 * Invoke the given function on every possible subclass of this
478 * class. This must be a resolved class.
480 void forEachSubclass(const std::function<void(const php::Class*)>&) const;
483 * Given two lists of classes, calculate the union between them (in
484 * canonical form). A list of size 1 represents a single class, and
485 * a larger list represents an intersection of classes. The input
486 * lists are assumed to be in canonical form. If the output is an
487 * empty list, the union is *all* classes (corresponding to TObj or
488 * TCls). This function is really an implementation detail of
489 * union_of() and not a general purpose interface.
491 static TinyVector<Class, 2> combine(folly::Range<const Class*> classes1,
492 folly::Range<const Class*> classes2,
493 bool isSub1,
494 bool isSub2,
495 bool nonRegular1,
496 bool nonRegular2);
498 * Given two lists of classes, calculate the intersection between
499 * them (in canonical form). A list of size 1 represents a single
500 * class, and a larger list represents an intersection of
501 * classes. The input lists are assumed to be in canonical form. If
502 * the output is an empty list, the intersection is empty
503 * (equivalent to Bottom). This function is really an implementation
504 * detail of intersection_of() and not a general purpose interface.
506 static TinyVector<Class, 2> intersect(folly::Range<const Class*> classes1,
507 folly::Range<const Class*> classes2,
508 bool nonRegular1,
509 bool nonRegular2,
510 bool& nonRegularOut);
513 * Given a list of classes, return a new list of classes
514 * representing all of the non-regular classes removed (and
515 * canonicalized). If the output list is empty, there are no regular
516 * classes.
518 static TinyVector<Class, 2>
519 removeNonRegular(folly::Range<const Class*> classes);
522 * Given two lists of classes, calculate whether their intersection
523 * is non-empty. This is equivalent to calling intersect and
524 * checking the result, but more efficient.
526 static bool couldBeIsect(folly::Range<const Class*> classes1,
527 folly::Range<const Class*> classes2,
528 bool nonRegular1,
529 bool nonRegular2);
531 * Convert this class to/from an opaque integer. The integer is
532 * "pointerish" (has upper bits cleared), so can be used in
533 * something like CompactTaggedPtr. It is not, however, guaranteed
534 * to be aligned (lower bits may be set).
536 uintptr_t toOpaque() const { return val.toOpaque(); }
537 static Class fromOpaque(uintptr_t o) {
538 return Class{decltype(val)::fromOpaque(o)};
541 size_t hash() const { return val.toOpaque(); }
543 private:
544 explicit Class(Either<SString,ClassInfo*> val) : val{val} {}
546 template <typename F>
547 static void visitEverySub(folly::Range<const Class*>, bool, const F&);
548 static ClassInfo* commonAncestor(ClassInfo*, ClassInfo*);
549 static TinyVector<Class, 2> canonicalizeIsects(const TinyVector<Class, 8>&, bool);
550 private:
551 friend std::string show(const Class&);
552 friend struct ::HPHP::HHBBC::Index;
553 friend struct ::HPHP::HHBBC::PublicSPropMutations;
554 friend struct ::HPHP::HHBBC::ClassInfo;
555 Either<SString,ClassInfo*> val;
559 * This is an abstraction layer to represent possible runtime function
560 * resolutions.
562 * Internally, this may only know the name of the function (or method), or we
563 * may know exactly which source-code-level function it refers to, or we may
564 * only have ruled it down to one of a few functions in a class hierarchy. The
565 * interpreter can treat all these cases the same way using this.
567 struct Func {
569 * Returns the name of this function. Non-null guarantee.
571 SString name() const;
574 * If this resolved function represents exactly one php::Func, return it.
576 const php::Func* exactFunc() const;
579 * Returns whether this resolved function is definitely safe to constant fold.
581 bool isFoldable() const;
584 * Whether this function could have reified generics
586 bool couldHaveReifiedGenerics() const;
589 * Returns whether this resolved function might distinguish being called
590 * dynamically versus being called normally (IE, might raise a notice).
592 bool mightCareAboutDynCalls() const;
595 * Returns whether this resolved function might be a builtin.
597 bool mightBeBuiltin() const;
600 * Minimum/maximum bound on the number of non-variadic parameters of the
601 * function.
603 uint32_t minNonVariadicParams() const;
604 uint32_t maxNonVariadicParams() const;
607 * Coeffects
609 const RuntimeCoeffects* requiredCoeffects() const;
610 // Returns nullptr if we cant tell whether there are coeffect rules
611 const CompactVector<CoeffectRule>* coeffectRules() const;
613 struct FuncInfo;
614 struct FuncFamily;
616 private:
617 friend struct ::HPHP::HHBBC::Index;
618 struct FuncName {
619 FuncName(SString n, bool r) : name{n}, renamable{r} {}
620 bool operator==(FuncName o) const { return name == o.name; }
621 SString name;
622 bool renamable;
624 struct MethodName {
625 bool operator==(MethodName o) const { return name == o.name; }
626 SString name;
628 struct Method {
629 const php::Func* func;
631 // Like Method, but the method is not guaranteed to actually exist
632 // (this only matters for things like exactFunc()).
633 struct MethodOrMissing {
634 const php::Func* func;
636 // Method/Func is known to not exist
637 struct Missing {
638 SString name;
640 // Group of methods (a wrapper around a FuncFamily).
641 struct MethodFamily {
642 FuncFamily* family;
643 bool regularOnly;
645 // Simultaneously a group of func families. Any data must be
646 // intersected across all of the func families in the list. Used for
647 // method resolution on a DCls where isIsect() is true.
648 struct Isect {
649 CompactVector<FuncFamily*> families;
650 bool regularOnly{false};
652 using Rep = boost::variant< FuncName
653 , MethodName
654 , FuncInfo*
655 , Method
656 , MethodFamily
657 , MethodOrMissing
658 , Missing
659 , Isect
662 private:
663 explicit Func(Rep);
664 friend std::string show(const Func&);
666 private:
667 Rep val;
671 * Produce a trace-able string for a res::Func or res::Class.
673 std::string show(const Func&);
674 std::string show(const Class&);
678 //////////////////////////////////////////////////////////////////////
681 * This class encapsulates the known facts about the program, with a
682 * whole-program view.
684 * This structure contains unowned pointers into the php::Program it
685 * was created for. It should not out-live the Program.
687 * The const member functions of this class are thread safe for
688 * concurrent reads and writes. The non-const functions should be
689 * called in a single threaded context only (they are used during the
690 * "update" step in between whole program analysis rounds).
692 struct Index {
693 // The input used to build the Index is largely the extern-worker
694 // refs representing the program components. However, some
695 // additional metadata is needed locally to know what the refs
696 // represent (and schedule some initial jobs).
697 struct Input {
698 template <typename T> using R = extern_worker::Ref<std::unique_ptr<T>>;
700 struct ClassMeta {
701 R<php::Class> cls;
702 LSString name;
703 std::vector<SString> dependencies;
704 LSString closureContext;
705 bool isClosure;
708 struct FuncMeta {
709 R<php::Func> func;
710 LSString name;
711 LSString methCallerUnit; // nullptr if not MethCaller
714 struct UnitMeta {
715 R<php::Unit> unit;
716 LSString name;
719 static std::vector<SString> makeDeps(const php::Class&);
721 std::vector<ClassMeta> classes;
722 std::vector<UnitMeta> units;
723 std::vector<FuncMeta> funcs;
727 * Create an Index for a php::Program. Performs some initial
728 * analysis of the program.
730 Index(Input,
731 Config,
732 std::unique_ptr<coro::TicketExecutor>,
733 std::unique_ptr<extern_worker::Client>,
734 DisposeCallback,
735 StructuredLogEntry*);
736 ~Index();
739 * The index operates in two modes: frozen, and unfrozen.
741 * Conceptually, the index is mutable and may acquire new
742 * information until it has been frozen, and once frozen, it retains
743 * the information it had at the point it was frozen.
745 * The reason this exists is because certain functions on the index
746 * may cause it to need to consult information in the bodies of
747 * functions other than the Context passed in. Specifically, if the
748 * interpreter tries to look up the return type for a callee in a
749 * given CallContext, the index may choose to recursively invoke
750 * type inference on that callee's function body to see if more
751 * precise information can be determined, unless it is frozen.
753 * This is fine until the final pass, because all bytecode is
754 * read-only at that stage. However, in the final pass, other
755 * threads might be optimizing a callee's bytecode and changing it,
756 * so we should not be reading from it to perform type inference
757 * concurrently. Freezing the index tells it it can't do that
758 * anymore.
760 * These are the functions to query and transition to frozen state.
762 bool frozen() const;
763 void freeze();
764 void thaw();
767 * Throw away data structures that won't be needed during or after
768 * analysis. Currently just some data structures only used while
769 * building the index.
771 void cleanup_pre_analysis();
774 * Throw away data structures that won't be needed during or after
775 * the final pass. Currently the dependency map, which can take a
776 * long time to destroy.
778 void cleanup_for_final();
781 * Throw away data structures that won't be needed after the emit
782 * stage.
784 void cleanup_post_emit();
787 * Access the StructuredLogEntry that the Index is using (if any).
789 StructuredLogEntry* sample() const;
792 * Access the php::Program this Index is analyzing.
794 const php::Program& program() const;
797 * Obtain a pointer to the unit which defined the given func.
799 const php::Unit* lookup_func_unit(const php::Func&) const;
800 const php::Unit* lookup_func_original_unit(const php::Func&) const;
803 * Obtain a pointer to the unit which defined the given class.
805 const php::Unit* lookup_class_unit(const php::Class&) const;
808 * Obtain a pointer to the class which defines the given class
809 * constant.
811 const php::Class* lookup_const_class(const php::Const&) const;
814 * Obtain a pointer to the class which serves as the context for the
815 * given class. For non-closures, this is just the input, but may be
816 * different in closures.
818 const php::Class* lookup_closure_context(const php::Class&) const;
821 * Call the given callback for each (top-level) func defined in the
822 * given Unit.
824 void for_each_unit_func(const php::Unit&,
825 std::function<void(const php::Func&)>) const;
826 void for_each_unit_func_mutable(php::Unit&,
827 std::function<void(php::Func&)>);
830 * Call the given callback for each class defined in the given Unit.
832 void for_each_unit_class(const php::Unit&,
833 std::function<void(const php::Class&)>) const;
834 void for_each_unit_class_mutable(php::Unit&,
835 std::function<void(php::Class&)>);
838 * Find all the closures created inside the context of a given
839 * php::Class.
841 const CompactVector<const php::Class*>*
842 lookup_closures(const php::Class*) const;
845 * Find all the extra methods associated with a class from its
846 * traits.
848 const hphp_fast_set<const php::Func*>*
849 lookup_extra_methods(const php::Class*) const;
852 * Try to find a res::Class for a given php::Class.
854 * Note, the returned class may or may not be *defined* at the
855 * program point you care about (it could be non-hoistable, even
856 * though it's unique, for example).
858 * Returns a name-only resolution if there are no legal
859 * instantiations of the class, or if there is more than one.
861 res::Class resolve_class(const php::Class*) const;
864 * Try to resolve which class will be the class named `name' from a
865 * given context, if we can resolve it to a single class.
867 * Note, the returned class may or may not be *defined* at the
868 * program point you care about (it could be non-hoistable, even
869 * though it's unique, for example).
871 * Returns std::nullopt if we can't prove the supplied name must be a
872 * object type. (E.g. if there are type aliases.)
874 Optional<res::Class> resolve_class(Context, SString name) const;
877 * Find a type-alias with the given name. If a nullptr is returned,
878 * then no type-alias exists with that name.
880 const php::TypeAlias* lookup_type_alias(SString name) const;
883 * Try to resolve self/parent types for the given context
885 Optional<res::Class> selfCls(const Context& ctx) const;
886 Optional<res::Class> parentCls(const Context& ctx) const;
888 template <typename T>
889 struct ResolvedInfo {
890 AnnotType type;
891 bool nullable;
892 T value;
896 * Try to resolve name, looking through TypeAliases and enums.
898 ResolvedInfo<Optional<res::Class>> resolve_type_name(SString name) const;
901 * Resolve a closure class.
903 * Returns both a resolved Class, and the actual php::Class for the
904 * closure.
906 std::pair<res::Class, const php::Class*>
907 resolve_closure_class(Context ctx, SString name) const;
910 * Return a resolved class for a builtin class.
912 * Pre: `name' must be the name of a class defined in a systemlib.
914 res::Class builtin_class(SString name) const;
917 * Try to resolve a function named `name' from a given context.
919 * Note, the returned function may or may not be defined at the
920 * program point (it could require a function autoload that might
921 * fail).
923 res::Func resolve_func(Context, SString name) const;
926 * Try to resolve a method named `name' with a this type of
927 * `thisType' within a given Context.
929 * The type of `thisType' determines if the method is meant to be
930 * static or not. A this type of BCls is a static method and a BObj
931 * is for an instance method.
933 * Note: a resolved method does not imply the function is actually
934 * callable at runtime. You still need to apply visibility checks,
935 * etc.
937 * Pre: thisType.subtypeOf(BCls) || thisType.subtypeOf(BObj)
939 res::Func resolve_method(Context, const Type& thisType, SString name) const;
942 * Resolve a class constructor for the supplied object type.
944 * Pre: obj.subtypeOf(BObj)
946 res::Func resolve_ctor(const Type& obj) const;
949 * Return a resolved class representing the base class of a wait
950 * handle (this will be a sub-class of Awaitable).
952 res::Class wait_handle_class() const;
955 * Give the Type in our type system that matches an hhvm
956 * TypeConstraint, subject to the information in this Index.
958 * This function returns a subtype of Cell, although TypeConstraints
959 * at runtime can match reference parameters. The caller should
960 * make sure to handle that case.
962 * For soft constraints (@), this function returns Cell.
964 * For some non-soft constraints (such as "Stringish"), this
965 * function may return a Type that is a strict supertype of the
966 * constraint's type.
968 * If something is known about the type of the object against which
969 * the constraint will be checked, it can be passed in to help
970 * disambiguate certain constraints (useful because we don't support
971 * arbitrary unions, or intersection).
973 Type lookup_constraint(Context, const TypeConstraint&,
974 const Type& t = TCell) const;
977 * If this function returns true, it is safe to assume that Type t
978 * will always satisfy TypeConstraint tc at run time.
980 bool satisfies_constraint(Context, const Type& t,
981 const TypeConstraint& tc) const;
984 * Returns true if the given type-hint (declared on the given class) might not
985 * be enforced at runtime (IE, it might map to mixed or be soft).
987 bool prop_tc_maybe_unenforced(const php::Class& propCls,
988 const TypeConstraint& tc) const;
991 * Returns true if the type constraint can contain a reified type
992 * Currently, only classes and interfaces are supported
994 bool could_have_reified_type(Context ctx, const TypeConstraint& tc) const;
997 * Returns a tuple containing a type after the parameter type verification
998 * and a flag indicating whether the verification was effect free.
1000 std::tuple<Type, bool>
1001 verify_param_type(Context ctx, uint32_t paramId, Type t) const;
1004 * Lookup metadata about the constant access `cls'::`name', in the
1005 * current context `ctx'. The returned metadata not only includes
1006 * the best known type of the constant, but whether it is definitely
1007 * found, and whether accessing the constant might throw. This
1008 * function is responsible for walking the class hierarchy to find
1009 * all possible constants and combining the results. This is
1010 * intended to be the source of truth about constants during
1011 * analysis.
1013 * This function only looks up non-type, non-context constants.
1015 ClsConstLookupResult<>
1016 lookup_class_constant(Context ctx, const Type& cls, const Type& name) const;
1019 * Lookup metadata about the constant access `cls'::`name', where
1020 * that constant is meant to be a type-constant. The returned
1021 * metadata includes the best known type of the resolved
1022 * type-structure, whether it was found, and whether it was
1023 * abstract. This is intended to be the source of truth about
1024 * type-constants during analysis. The returned type-structure type
1025 * will always be static.
1027 * By default, lookup_class_type_constant calls
1028 * resolve_type_structure to resolve any found type-structure. This
1029 * behavior can be overridden by providing a customer resolver.
1031 using ClsTypeConstLookupResolver =
1032 std::function<TypeStructureResolution(const php::Const&,const php::Class&)>;
1034 ClsTypeConstLookupResult<>
1035 lookup_class_type_constant(
1036 const Type& cls,
1037 const Type& name,
1038 const ClsTypeConstLookupResolver& resolver = {}) const;
1041 * Lookup what the best known Type for a constant would be, using a
1042 * given Index and Context, if a constant of that name were defined.
1044 Type lookup_constant(Context ctx, SString cnsName) const;
1047 * Return true if the return value of the function might depend on arg.
1049 bool func_depends_on_arg(const php::Func* func, int arg) const;
1052 * If func is effect-free when called with args, and it returns a constant,
1053 * return that constant; otherwise return TInitCell.
1055 Type lookup_foldable_return_type(Context ctx,
1056 const CallContext& calleeCtx) const;
1059 * Return the best known return type for a resolved function, in a
1060 * context insensitive way. Returns TInitCell at worst.
1062 Type lookup_return_type(Context, MethodsInfo*, res::Func,
1063 Dep dep = Dep::ReturnTy) const;
1064 Type lookup_return_type(Context, MethodsInfo*, const php::Func*,
1065 Dep dep = Dep::ReturnTy) const;
1068 * Return the best known return type for a resolved function, given
1069 * the supplied calling context. Returns TInitCell at worst.
1071 * During analyze phases, this function may re-enter analyze in
1072 * order to interpret the callee with these argument types.
1074 Type lookup_return_type(Context caller,
1075 MethodsInfo*,
1076 const CompactVector<Type>& args,
1077 const Type& context,
1078 res::Func,
1079 Dep dep = Dep::ReturnTy) const;
1082 * Look up raw return type information for an unresolved
1083 * function. This is the best known return type, and the number of
1084 * refinements done to that type.
1086 * This function does not register a dependency on the return type
1087 * information.
1089 * Nothing may be writing to the index when this function is used,
1090 * but concurrent readers are allowed.
1092 std::pair<Type, size_t> lookup_return_type_raw(const php::Func*) const;
1095 * Return the best known types of a closure's used variables (on
1096 * entry to the closure). The function is the closure body.
1098 * If move is true, the value will be moved out of the index. This
1099 * should only be done at emit time. (note that the only other user
1100 * of this info is analysis, which only uses it when processing the
1101 * owning class, so its safe to kill after emitting the owning
1102 * unit).
1104 CompactVector<Type>
1105 lookup_closure_use_vars(const php::Func*,
1106 bool move = false) const;
1109 * Return the availability of $this on entry to the provided method.
1110 * If the Func provided is not a method of a class false is
1111 * returned.
1113 bool lookup_this_available(const php::Func*) const;
1116 * Returns the parameter preparation kind (if known) for parameter
1117 * `paramId' on the given resolved Func.
1119 PrepKind lookup_param_prep(Context, res::Func, uint32_t paramId) const;
1122 * Returns the number of inout parameters expected by func (if known).
1124 Optional<uint32_t> lookup_num_inout_params(Context, res::Func) const;
1127 * Returns whether the function's return value is readonly
1129 TriBool lookup_return_readonly(Context, res::Func) const;
1132 * Returns whether the function is marked as readonly
1134 TriBool lookup_readonly_this(Context, res::Func) const;
1137 * Returns the control-flow insensitive inferred private instance
1138 * property types for a Class. The Class doesn't need to be
1139 * resolved, because private properties don't depend on the
1140 * inheritance hierarchy.
1142 * The Index tracks the largest types for private properties that
1143 * are guaranteed to hold at any program point.
1145 * If move is true, the value will be moved out of the index. This
1146 * should only be done at emit time. (note that the only other user
1147 * of this info is analysis, which only uses it when processing the
1148 * owning class, so its safe to kill after emitting the owning
1149 * unit).
1151 PropState lookup_private_props(const php::Class*,
1152 bool move = false) const;
1155 * Returns the control-flow insensitive inferred private static
1156 * property types for a Class. The class doesn't need to be
1157 * resolved for the same reasons as for instance properties.
1159 * The Index tracks the largest types for private static properties
1160 * that are guaranteed to hold at any program point.
1162 * If move is true, the value will be moved out of the index. This
1163 * should only be done at emit time. (note that the only other user
1164 * of this info is analysis, which only uses it when processing the
1165 * owning class, so its safe to kill after emitting the owning
1166 * unit).
1168 PropState lookup_private_statics(const php::Class*,
1169 bool move = false) const;
1170 PropState lookup_public_statics(const php::Class*) const;
1173 * Lookup metadata about the static property access `cls'::`name',
1174 * in the current context `ctx'. The returned metadata not only
1175 * includes the best known type of the property, but whether it is
1176 * definitely found, and whether the access might raise for various
1177 * reasons. This function is responsible for walking the class
1178 * hierarchy to find the appropriate property while applying
1179 * accessibility rules. This is intended to be the source of truth
1180 * about static properties during analysis.
1182 PropLookupResult<> lookup_static(Context ctx,
1183 const PropertiesInfo& privateProps,
1184 const Type& cls,
1185 const Type& name) const;
1188 * Lookup if initializing (which is a side-effect of several bytecodes) the
1189 * given class might raise.
1191 bool lookup_class_init_might_raise(Context, res::Class) const;
1194 * Lookup the best known type for a public (non-static) property. Since we
1195 * don't do analysis on public properties, this just inferred from the
1196 * property's type-hint (if enforced).
1198 Type lookup_public_prop(const Type& obj, const Type& name) const;
1199 Type lookup_public_prop(const php::Class* cls, SString name) const;
1202 * We compute the interface vtables in a separate thread. It needs
1203 * to be joined (in single threaded context) before calling
1204 * lookup_iface_vtable_slot.
1206 void join_iface_vtable_thread() const;
1209 * Returns the computed vtable slot for the given class, if it's an interface
1210 * that was given a vtable slot. No two interfaces implemented by the same
1211 * class will share the same vtable slot. May return kInvalidSlot, if the
1212 * given class isn't an interface or if it wasn't assigned a slot.
1214 Slot lookup_iface_vtable_slot(const php::Class*) const;
1217 * Return the DependencyContext for ctx.
1219 DependencyContext dependency_context(const Context& ctx) const;
1222 * Determine whether to use class-at-a-time, or function-at-a-time
1223 * dependencies.
1225 * Must be called in single-threaded context.
1227 void use_class_dependencies(bool f);
1230 * Merge the type `val' into the known type for static property
1231 * `cls'::`name'. Depending on what we know about `cls' and `name',
1232 * this might affect multiple properties. This function is
1233 * responsible for walking the class hierarchy to find the
1234 * appropriate property while applying accessibility
1235 * rules. Mutations of AttrConst properties are ignored unless
1236 * `ignoreConst' is set to true. If `checkUB' is true, upper-bound
1237 * type constraints are consulted in addition to the normal type
1238 * constraints.
1240 * The result tells you the subtype of val that would be
1241 * successfully set (according to the type constraints), and if the
1242 * mutation would throw or not.
1244 PropMergeResult<> merge_static_type(Context ctx,
1245 PublicSPropMutations& publicMutations,
1246 PropertiesInfo& privateProps,
1247 const Type& cls,
1248 const Type& name,
1249 const Type& val,
1250 bool checkUB = false,
1251 bool ignoreConst = false,
1252 bool mustBeReadOnly = false) const;
1255 * Initialize the initial types for public static properties. This should be
1256 * done after rewriting initial property values, as that affects the types.
1258 void init_public_static_prop_types();
1261 * Initialize the initial "may have bad initial value" bit for
1262 * properties. By initially setting this before analysis, we save
1263 * redundant re-analyzes.
1265 void preinit_bad_initial_prop_values();
1268 * Attempt to pre-resolve as many type-structures as possible in
1269 * type-constants and type-aliases.
1271 void preresolve_type_structures();
1274 * Refine the types of the class constants defined by an 86cinit,
1275 * based on a round of analysis.
1277 * No other threads should be using ctx.cls->constants or deps when
1278 * this function is called.
1280 * Merges the set of Contexts that depended on the constants defined
1281 * by this 86cinit.
1283 void refine_class_constants(
1284 const Context& ctx,
1285 const CompactVector<std::pair<size_t, Type>>& resolved,
1286 DependencyContextSet& deps);
1289 * Refine the types of the constants defined by a function, based on
1290 * a round of analysis.
1292 * Constants not defined by a pseudomain are considered unknowable
1294 * No other threads should be calling functions on this Index when
1295 * this function is called.
1297 * Merges the set of Contexts that depended on the constants defined
1298 * by this php::Func into deps.
1300 void refine_constants(const FuncAnalysisResult& fa,
1301 DependencyContextSet& deps);
1304 * Refine the return type for a function, based on a round of
1305 * analysis.
1307 * No other threads should be calling functions on this Index when
1308 * this function is called.
1310 * Merges the set of Contexts that depended on the return type of
1311 * this php::Func into deps.
1313 void refine_return_info(const FuncAnalysisResult& fa,
1314 DependencyContextSet& deps);
1317 * Refine the used var types for a closure, based on a round of
1318 * analysis.
1320 * No other threads should be calling functions on this Index when
1321 * this function is called.
1323 * Returns: true if the types have changed.
1325 bool refine_closure_use_vars(const php::Class*,
1326 const CompactVector<Type>&);
1329 * Refine the private property types for a class, based on a round
1330 * of analysis.
1332 * No other threads should be calling functions on this Index when
1333 * this function is called.
1335 void refine_private_props(const php::Class* cls,
1336 const PropState&);
1339 * Refine the static private property types for a class, based on a
1340 * round of analysis.
1342 * No other threads should be calling functions on this Index when
1343 * this function is called.
1345 void refine_private_statics(const php::Class* cls,
1346 const PropState&);
1349 * Record in the index that the given set of public static property mutations
1350 * has been found while analyzing the given function. During a round of
1351 * analysis, the mutations are gathered from the analysis results for each
1352 * function, recorded in the index, and then refine_public_statics is called
1353 * to process the mutations and update the index.
1355 * No other threads should be calling functions on this Index when this
1356 * function is called.
1358 void record_public_static_mutations(const php::Func& func,
1359 PublicSPropMutations mutations);
1363 * If we resolve the intial value of a public property, we need to
1364 * tell the refine_public_statics phase about it, because the init
1365 * value won't be included in the mutations any more.
1367 * Note that we can't modify the initial value here, because other
1368 * threads might be reading it (via loookup_public_static), so we
1369 * set a flag to tell us to update it during the next
1370 * refine_public_statics pass.
1372 void update_static_prop_init_val(const php::Class* cls,
1373 SString name) const;
1375 * After a round of analysis with all the public static property mutations
1376 * being recorded with record_public_static_mutations, the types can be
1377 * reflected into the index for use during another type inference pass.
1379 * No other threads should be calling functions on this Index when this
1380 * function is called.
1382 * Merges the set of Contexts that depended on a public static property whose
1383 * type has changed.
1385 void refine_public_statics(DependencyContextSet& deps);
1388 * Refine whether the given class has properties with initial values which
1389 * might violate their type-hints.
1391 * No other threads should be calling functions on this Index when this
1392 * function is called.
1394 void refine_bad_initial_prop_values(const php::Class* cls,
1395 bool value,
1396 DependencyContextSet& deps);
1399 * Mark any properties in cls that definitely do not redeclare a property in
1400 * the parent, which has an inequivalent type-hint.
1402 void mark_no_bad_redeclare_props(php::Class& cls) const;
1405 * Rewrite the initial values of any AttrSystemInitialValue properties to
1406 * something more suitable for its type-hint, and add AttrNoImplicitNullable
1407 * where appropriate.
1409 * This must be done before any analysis is done, as the initial values
1410 * affects the analysis.
1412 void rewrite_default_initial_values() const;
1415 * Return true if the resolved function supports async eager return.
1417 TriBool supports_async_eager_return(res::Func rfunc) const;
1420 * Return true if the function is effect free.
1422 bool is_effect_free(Context, res::Func rfunc) const;
1423 bool is_effect_free(Context, const php::Func* func) const;
1424 bool is_effect_free_raw(const php::Func* func) const;
1427 * Do any necessary fixups to a return type.
1429 * Note that eg for an async function it will map Type to
1430 * WaitH<Type>.
1432 void fixup_return_type(const php::Func*, Type&) const;
1435 * Return true if we know for sure that one php::Class must derive
1436 * from another at runtime, in all possible instantiations.
1438 bool must_be_derived_from(const php::Class*,
1439 const php::Class*) const;
1441 struct IndexData;
1442 private:
1443 Index(const Index&) = delete;
1444 Index& operator=(Index&&) = delete;
1446 private:
1447 friend struct PublicSPropMutations;
1449 res::Func resolve_func_helper(const php::Func*, SString) const;
1450 res::Func do_resolve(const php::Func*) const;
1452 template<bool getSuperType>
1453 Type get_type_for_constraint(Context,
1454 const TypeConstraint&,
1455 const Type&) const;
1457 struct ConstraintResolution;
1460 * Try to resolve name in the given context. Follows TypeAliases.
1462 ConstraintResolution resolve_named_type(
1463 const Context& ctx, SString name, const Type& candidate) const;
1465 ConstraintResolution get_type_for_annotated_type(
1466 Context ctx, AnnotType annot, bool nullable,
1467 SString name, const Type& candidate) const;
1469 void init_return_type(const php::Func* func);
1471 template <typename F>
1472 bool visit_every_dcls_cls(const DCls&, const F&) const;
1474 template <typename P, typename G>
1475 static res::Func rfunc_from_dcls(const DCls&, SString, const P&, const G&);
1477 private:
1478 std::unique_ptr<IndexData> const m_data;
1481 //////////////////////////////////////////////////////////////////////
1484 * Used for collecting all mutations of public static property types.
1486 struct PublicSPropMutations {
1487 private:
1488 friend struct Index;
1490 struct KnownKey {
1491 bool operator<(KnownKey o) const {
1492 if (cinfo != o.cinfo) return cinfo < o.cinfo;
1493 return prop < o.prop;
1496 ClassInfo* cinfo;
1497 SString prop;
1500 using UnknownMap = std::map<SString,Type>;
1501 using KnownMap = std::map<KnownKey,Type>;
1503 // Public static property mutations are actually rare, so defer allocating the
1504 // maps until we actually see one.
1505 struct Data {
1506 bool m_nothing_known{false};
1507 UnknownMap m_unknown;
1508 KnownMap m_known;
1510 std::unique_ptr<Data> m_data;
1512 Data& get();
1514 void mergeKnown(const ClassInfo* ci, const php::Prop& prop, const Type& val);
1515 void mergeUnknownClass(SString prop, const Type& val);
1516 void mergeUnknown(Context);
1519 //////////////////////////////////////////////////////////////////////