2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-2014 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_VM_CLASS_H_
18 #define incl_HPHP_VM_CLASS_H_
20 #include "hphp/runtime/base/types.h"
21 #include "hphp/runtime/base/attr.h"
22 #include "hphp/runtime/base/rds.h"
23 #include "hphp/runtime/base/repo-auth-type.h"
24 #include "hphp/runtime/base/type-array.h"
25 #include "hphp/runtime/base/type-string.h"
26 #include "hphp/runtime/base/typed-value.h"
27 #include "hphp/runtime/vm/fixed-string-map.h"
28 #include "hphp/runtime/vm/indexed-string-map.h"
29 #include "hphp/runtime/vm/instance-bits.h"
30 #include "hphp/runtime/vm/preclass.h"
32 #include "hphp/util/default-ptr.h"
34 #include <boost/range/iterator_range.hpp>
42 ///////////////////////////////////////////////////////////////////////////////
47 struct HhbcExtClassInfo
;
50 namespace Native
{ struct NativeDataInfo
; }
52 ///////////////////////////////////////////////////////////////////////////////
54 using ClassPtr
= AtomicSmartPtr
<Class
>;
57 * Class represents the full definition of a user class in a given request
60 * See PreClass for more on the distinction.
62 * The method table is allocated at negative offset from the start of the Class
63 * object, and the method slot is used as the negative offset from the object
64 * to index into the method table.
67 * Func Slot n (offset -(n+1)) --> | |
71 * Func Slot 1 (offset -2) ------> | |
73 * Func Slot 0 (offset -1) ------> | |
74 * Class* -----------------------> +------------+
80 struct Class
: AtomicCountable
{
82 /////////////////////////////////////////////////////////////////////////////
88 * @see: Class::avail()
97 * Instance property information.
100 // m_name is "" for inaccessible properties (i.e. private properties
101 // declared by parents).
103 LowStringPtr m_mangledName
;
104 LowStringPtr m_originalMangledName
;
105 // First parent class that declares this property.
108 LowStringPtr m_typeConstraint
;
109 // When built in RepoAuthoritative mode, this is a control-flow
110 // insensitive, always-true type assertion for this property. (It may be
111 // Gen if there was nothing interesting known.)
112 RepoAuthType m_repoAuthType
;
113 LowStringPtr m_docComment
;
118 * Static property information.
123 LowStringPtr m_typeConstraint
;
124 LowStringPtr m_docComment
;
125 // Most derived class that declared this property.
127 // Used if (m_class == this).
129 RepoAuthType m_repoAuthType
;
134 * Class constant information.
137 // Most derived class that declared this constant.
141 LowStringPtr m_phpCode
;
142 LowStringPtr m_typeConstraint
;
146 * Initialization vector for declared properties.
148 * This is a vector which contains default values for all of a Class's
149 * declared instance properties. It is used when instantiating new objects
156 const PropInitVec
& operator=(const PropInitVec
&);
158 using iterator
= TypedValueAux
*;
164 TypedValueAux
& operator[](size_t i
);
165 const TypedValueAux
& operator[](size_t i
) const;
167 void push_back(const TypedValue
& v
);
170 * Make a smart-allocated copy of `src'.
172 static PropInitVec
* allocWithSmartAllocator(const PropInitVec
& src
);
174 static constexpr size_t dataOff() {
175 return offsetof(PropInitVec
, m_data
);
179 PropInitVec(const PropInitVec
&);
181 TypedValueAux
* m_data
;
189 using MethodMap
= FixedStringMap
<Slot
, false, Slot
>;
190 using MethodMapBuilder
= FixedStringMapBuilder
<Func
*, Slot
, false, Slot
>;
191 using InterfaceMap
= IndexedStringMap
<LowClassPtr
, true, int>;
192 using RequirementMap
= IndexedStringMap
<
193 const PreClass::ClassRequirement
*, true, int>;
195 using TraitAliasVec
= std::vector
<PreClass::TraitAliasRule::NamePair
>;
198 /////////////////////////////////////////////////////////////////////////////
199 // Creation and destruction.
202 * Allocate a new Class object.
204 * Eventually deallocated using atomicRelease(), but can go through some
205 * phase changes before that (see destroy()).
207 static Class
* newClass(PreClass
* preClass
, Class
* parent
);
210 * Called when a Class becomes unreachable.
212 * This may happen before its refcount hits zero if it is still referred to
215 * - any derived Class;
216 * - any Class that implements it (for interfaces); or
217 * - any Class that uses it (for traits)
219 * Such referring classes must also be logically dead at the time destroy()
220 * is called. However, since we don't have back pointers to find them,
221 * instead we leave the Class in a zombie state. When we try to instantiate
222 * one of its referrers, we will notice that it depends on a zombie and
223 * destroy *that*, releasing its reference to this Class.
228 * Called when the (atomic) refcount hits zero.
230 * The Class is completely dead at this point, and its memory is freed
233 void atomicRelease();
237 * Free any references to child classes, interfaces, and traits.
239 * releaseRefs() is called when a Class is put into the zombie state. It's
240 * safe to call multiple times, so it is also called from the destructor (in
241 * case we bypassed the zombie state).
247 * Whether this class has been logically destroyed, but needed to be
248 * preserved due to outstanding references.
250 bool isZombie() const;
253 * Check whether a Class from a previous request is available to be defined.
254 * The caller should check that it has the same PreClass that is being
255 * defined. Being available means that the parent, the interfaces, and the
256 * traits are already defined (or become defined via autoload, if tryAutoload
259 * @returns: Avail::True: if it's available
260 * Avail::Fail: if at least one of the parent, interfaces, and
261 * traits is not defined at all at this point
262 * Avail::False: if at least one of the parent, interfaces, and
263 * traits is defined but does not correspond to this
266 * The parent parameter is used for two purposes: first, it lets us avoid
267 * looking up the active parent class for each potential Class*; and second,
268 * it is used on Fail to return the problem class so the caller can report
269 * the error correctly.
271 Avail
avail(Class
*& parent
, bool tryAutoload
= false) const;
274 /////////////////////////////////////////////////////////////////////////////
275 // Pre- and post-allocations. [const]
278 * The start of malloc'd memory for `this' (i.e., including the method
281 LowFuncPtr
* mallocPtrFromThis() const;
284 * Pointer to the array of Class pointers, allocated immediately after
285 * `this', which contain this class's inheritance hierarchy (including `this'
286 * as the last element).
288 const LowClassPtr
* classVec() const;
291 * The size of the classVec.
293 unsigned classVecLen() const;
296 /////////////////////////////////////////////////////////////////////////////
300 * Determine if this represents a non-strict subtype of `cls'.
302 * Returns uint64_t instead of bool because it's called directly from the TC.
304 uint64_t classof(const Class
* cls
) const;
307 * Whether this class implements an interface called `name'.
309 bool ifaceofDirect(const StringData
* name
) const;
312 * Assuming this and cls are both regular classes (not interfaces or traits),
313 * return their lowest common ancestor, or nullptr if they're unrelated.
315 const Class
* commonAncestor(const Class
* cls
) const;
318 /////////////////////////////////////////////////////////////////////////////
319 // Basic info. [const]
322 * The name, PreClass, and parent class of this class.
324 const StringData
* name() const;
325 const PreClass
* preClass() const;
326 Class
* parent() const;
329 * Uncounted String names of this class and of its parent.
331 StrNR
nameStr() const;
332 StrNR
parentStr() const;
335 * The attributes on this class.
340 * ObjectData attributes, to be set during instance initialization.
342 int getODAttrs() const;
345 * Whether we can load this class once and persist it across requests.
347 * Persistence is possible when a Class is uniquely named and is defined in a
348 * pseudomain that has no side-effects (except other persistent definitions).
350 * A class which satisfies isPersistent() may not actually /be/ persistent,
351 * if we had to allocate its RDS handle before we loaded the class.
353 * @see: classHasPersistentRDS()
355 bool isPersistent() const;
358 /////////////////////////////////////////////////////////////////////////////
359 // Magic methods. [const]
362 * Get the constructor, destructor, or __toString() method on this class, or
363 * nullptr if no such method exists.
365 * DeclaredCtor refers to a user-declared __construct() or ClassName(), as
366 * opposed to the default 86ctor() method generated by the compiler.
368 const Func
* getCtor() const;
369 const Func
* getDeclaredCtor() const;
370 const Func
* getDtor() const;
371 const Func
* getToString() const;
374 /////////////////////////////////////////////////////////////////////////////
375 // Builtin classes. [const]
378 * Is the class a builtin, whether PHP or C++?
380 bool isBuiltin() const;
383 * Return the ClassInfo for a C++ extension class.
385 const ClassInfo
* clsInfo() const;
388 * Custom initialization and destruction routines for C++ extension classes.
390 * instanceCtor() returns true iff the class is a C++ extension class.
392 BuiltinCtorFunction
instanceCtor() const;
393 BuiltinDtorFunction
instanceDtor() const;
396 * This value is the pointer adjustment from an ObjectData* to get to the
397 * property vector, for a builtin class. In other words, it's the number of
398 * bytes of subclass data following the ObjectData subobject.
400 int32_t builtinODTailSize() const;
403 * Whether this C++ extension class has opted into serialization.
405 * @requires: instanceCtor()
407 bool isCppSerializable() const;
410 * Whether this is a class for a Hack collection.
412 bool isCollectionClass() const;
415 /////////////////////////////////////////////////////////////////////////////
419 * Number of methods on this class.
421 * Note that this may differ from m_funcVecLen, since numMethods() is the
422 * exact number of methods, and m_funcVecLen is only required to be an upper
425 * In particular, outside of RepoAuth mode, trait methods are not transcluded
426 * into the Classes which use them, and we are conservative when initially
427 * counting methods since we do not resolve trait precedence first.
429 size_t numMethods() const;
432 * Get or set a method by its index in the funcVec, which is allocated
433 * contiguously before `this' in memory.
435 Func
* getMethod(Slot idx
) const;
436 void setMethod(Slot idx
, Func
* func
);
439 * Look up a method by name.
441 * Return null if no such method exists.
443 Func
* lookupMethod(const StringData
* methName
) const;
445 static void getMethodNames(const Class
* cls
, const Class
* ctx
, Array
& result
);
447 /////////////////////////////////////////////////////////////////////////////
448 // Property metadata. [const]
450 // Unless otherwise specified, the terms "declared instance properties" and
451 // "static properties" both refer to properties declared on this class as
452 // well as those declared on its ancestors. Note that this includes private
453 // properties in both cases.
456 * Number of declared instance properties or static properties.
458 size_t numDeclProperties() const;
459 size_t numStaticProperties() const;
462 * Number of declared instance properties that are actually accessible from
463 * this class's context.
465 * Only really used when iterating over an object's properties.
467 uint32_t declPropNumAccessible() const;
470 * The info vector for declared instance properties or static properties.
472 const Prop
* declProperties() const;
473 const SProp
* staticProperties() const;
476 * Look up the index of a declared instance property or static property.
478 * Return kInvalidSlot if no such property exists.
480 Slot
lookupDeclProp(const StringData
* propName
) const;
481 Slot
lookupSProp(const StringData
* sPropName
) const;
484 * The RepoAuthType of the declared instance property or static property at
485 * `index' in the corresponding table.
487 RepoAuthType
declPropRepoAuthType(Slot index
) const;
488 RepoAuthType
staticPropRepoAuthType(Slot index
) const;
491 * Whether this class has any properties that require deep initialization.
493 * Deep initialization means that the property cannot simply be memcpy'd when
494 * creating new objects.
496 bool hasDeepInitProps() const;
499 /////////////////////////////////////////////////////////////////////////////
500 // Property initialization. [const]
503 * Whether this Class requires initialization, either because of nonscalar
504 * instance property initializers, or simply due to having static properties.
506 bool needInitialization() const;
509 * Perform request-local initialization.
511 * For declared instance properties, this means creating a request-local copy
512 * of this Class's PropInitVec. This is necessary in order to accommodate
513 * non-scalar defaults (e.g., class constants), which not be consistent
516 * For static properties, this means setting up request-local memory for the
517 * actual static properties, if necessary, and initializing them to their
520 void initialize() const;
521 void initProps() const;
522 void initSProps() const;
525 * PropInitVec for this class's declared properties, with default values for
528 * This is the base from which the request-local copy is made.
530 const PropInitVec
& declPropInit() const;
533 * Vector of 86pinit non-scalar instance property initializer functions.
535 * These are invoked during initProps() to populate the copied PropInitVec.
537 const std::vector
<const Func
*>& pinitVec() const;
540 /////////////////////////////////////////////////////////////////////////////
541 // Property storage. [const]
544 * Initialize the RDS handles for the request-local PropInitVec and for the
547 void initPropHandle() const;
548 void initSPropHandles() const;
551 * RDS handle of the request-local PropInitVec.
553 RDS::Handle
propHandle() const;
556 * RDS handle for the static properties' is-initialized flag.
558 RDS::Handle
sPropInitHandle() const;
561 * RDS handle for the static property at `index'.
563 RDS::Handle
sPropHandle(Slot index
) const;
566 * Get the PropInitVec for the current request.
568 PropInitVec
* getPropData() const;
571 * Get the value of the static variable at `index' for the current request.
573 TypedValue
* getSPropData(Slot index
) const;
576 /////////////////////////////////////////////////////////////////////////////
577 // Property lookup and accessibility. [const]
580 * Get the slot and accessibility of the declared instance property `key' on
581 * this class from the context `ctx'.
583 * Accessibility refers to the public/protected/private attribute of the
584 * property. The value of `accessible' is output by reference.
586 * Return kInvalidInd iff the property was not declared on this class or any
587 * ancestor. Note that if `accessible' is true, then the property must
590 Slot
getDeclPropIndex(Class
* ctx
, const StringData
* key
,
591 bool& accessible
) const;
594 * Get the slot, visibility, and accessibility of the static property
595 * `sPropName on this class from the context `ctx'.
597 * Visibility refers to whether or not the property exists at all.
598 * Accessibility refers to the public/protected/private attribute of the
601 * Both `visible' and `accessible' are output by reference.
603 * Return kInvalidInd (and set `visible' to false) iff the property does not
604 * exist. Note also that if `accessible' is true, then the property must
607 Slot
findSProp(Class
* ctx
, const StringData
* sPropName
,
608 bool& visible
, bool& accessible
) const;
611 * Get the request-local value of the static property `sPropName', as well as
612 * its visibility and accessibility, from the context `ctx'.
614 * The behavior is identical to that of findSProp(), except substituting
615 * nullptr for kInvalidInd.
617 * May perform initialization.
619 TypedValue
* getSProp(Class
* ctx
, const StringData
* sPropName
,
620 bool& visible
, bool& accessible
) const;
623 * Identical to getSProp(), but the output is boxed.
625 * Used by the ext_zend_compat layer.
627 RefData
* zGetSProp(Class
* ctx
, const StringData
* sPropName
,
628 bool& visible
, bool& accessible
) const;
631 * Return whether or not the declared instance property described by `prop'
632 * is accessible from the context `ctx'.
634 static bool IsPropAccessible(const Prop
& prop
, Class
* ctx
);
637 /////////////////////////////////////////////////////////////////////////////
638 // Constants. [const]
641 * Number of class constants.
643 size_t numConstants() const;
646 * The info vector for this class's constants.
648 const Const
* constants() const;
651 * Whether this class has a constant named `clsCnsName'.
653 bool hasConstant(const StringData
* clsCnsName
) const;
656 * Look up the actual value of a class constant. Perform dynamic
657 * initialization if necessary.
659 * Return a Cell containing KindOfUninit if this class has no such constant.
661 * The returned Cell is guaranteed not to hold a reference counted object (it
662 * may, however, be KindOfString for a static string).
664 Cell
clsCnsGet(const StringData
* clsCnsName
) const;
667 * Look up a class constant's TypedValue if it doesn't require dynamic
668 * initialization. The index of the constant is output via `clsCnsInd'.
670 * Return nullptr if this class has no constant of the given name.
672 * The TypedValue represents the constant's value iff it is a scalar,
673 * otherwise it has m_type set to KindOfUninit. Non-scalar class constants
674 * need to run 86cinit code to determine their value at runtime.
676 const Cell
* cnsNameToTV(const StringData
* clsCnsName
, Slot
& clsCnsInd
) const;
679 * Provide the current runtime type of this class constant.
681 * This has predictive value for the translator.
683 DataType
clsCnsType(const StringData
* clsCnsName
) const;
686 /////////////////////////////////////////////////////////////////////////////
687 // Interfaces and traits.
690 * Interfaces this class declared in its "implements" clause.
692 boost::iterator_range
<const ClassPtr
*> declInterfaces() const;
695 * All interfaces implemented by this class, including those declared in
698 const InterfaceMap
& allInterfaces() const;
701 * Start and end offsets in m_methods of methods that come from used traits.
703 * The trait methods are precisely in [m_traitsBeginIdx, m_traitsEndIdx).
705 Slot
traitsBeginIdx() const;
706 Slot
traitsEndIdx() const;
709 * Traits used by this class.
711 * In RepoAuthoritative mode, we flatten all traits into their users in the
712 * compile phase, which leaves m_usedTraits empty as a result.
714 const std::vector
<ClassPtr
>& usedTraitClasses() const;
719 * This is only used by reflection.
721 const TraitAliasVec
& traitAliases() const;
724 * All trait and interface requirements imposed on this class, including
725 * those imposed by traits.
727 const RequirementMap
& allRequirements() const;
730 /////////////////////////////////////////////////////////////////////////////
734 * Offset of the declared instance property at `index' on an ObjectData
735 * instantiated from this class.
737 size_t declPropOffset(Slot index
) const;
740 * Whether instances of this class need to call a custom __init__ when
743 bool callsCustomInstanceInit() const;
746 /////////////////////////////////////////////////////////////////////////////
749 // Avoiding adding methods to this section.
752 * Whether this class can be made persistent---i.e., if AttrPersistent is set
753 * and all parents, interfaces, and traits for this class are persistent.
755 bool verifyPersistent() const;
758 * Get and set the RDS handle for the class with this class's name.
760 * We can burn these into the TC even when classes are not persistent, since
761 * only a single name-to-class mapping will exist per request.
763 RDS::Handle
classHandle() const;
764 void setClassHandle(RDS::Link
<Class
*> link
) const;
767 * Get and set the RDS-cached class with this class's name.
769 Class
* getCached() const;
773 * Set the instance bits on this class.
775 * The instance bits are a bitfield cache for instanceof checks. During
776 * warmup, we profile the classes and interfaces most commonly checked
777 * against in instanceof checks. Then we cache whether or not this Class
778 * satisifes the check in the corresponding bit.
780 void setInstanceBits();
781 void setInstanceBitsAndParents();
784 * NativeData type declared in <<__NativeData("Type")>>.
786 const Native::NativeDataInfo
* getNativeDataInfo() const;
789 * Get the underlying enum base type if this is an enum.
791 DataType
enumBaseTy() const;
794 /////////////////////////////////////////////////////////////////////////////
795 // Offset accessors. [static]
798 static constexpr ptrdiff_t f##Off() { \
799 return offsetof(Class, m_##f); \
810 /////////////////////////////////////////////////////////////////////////////
818 * Vector of (new name, original name) pairs, representing trait aliases.
820 TraitAliasVec m_traitAliases
;
823 * In RepoAuthoritative mode, we rely on trait flattening in the compile
824 * phase to import the contents of traits. As a result, m_usedTraits is
827 std::vector
<ClassPtr
> m_usedTraits
;
830 * Only used by reflection for method ordering. Whenever we have no traits
831 * (e.g., in repo mode, where traits are flattened), these will both be 0.
833 Slot m_traitsBeginIdx
{0};
834 Slot m_traitsEndIdx
{0};
837 * Builtin-specific data.
839 BuiltinCtorFunction m_instanceCtor
{nullptr};
840 BuiltinDtorFunction m_instanceDtor
{nullptr};
841 const ClassInfo
* m_clsInfo
{nullptr};
842 uint32_t m_builtinODTailSize
{0};
845 * Objects with the <<__NativeData("T")>> UA are allocated with extra space
846 * prior to the ObjectData structure itself.
848 const Native::NativeDataInfo
*m_nativeDataInfo
{nullptr};
852 * Allocate the ExtraData; done only when necessary.
854 void allocExtraData();
857 /////////////////////////////////////////////////////////////////////////////
861 using ConstMap
= IndexedStringMap
<Const
,true,Slot
>;
862 using PropMap
= IndexedStringMap
<Prop
,true,Slot
>;
863 using SPropMap
= IndexedStringMap
<SProp
,true,Slot
>;
866 TraitMethod(Class
* trait
, Func
* method
, Attr modifiers
)
869 , m_modifiers(modifiers
)
877 using TraitMethodList
= std::list
<TraitMethod
>;
878 using MethodToTraitListMap
= hphp_hash_map
<LowStringPtr
,
884 /////////////////////////////////////////////////////////////////////////////
888 Class(PreClass
* preClass
,
890 std::vector
<ClassPtr
>&& usedTraits
,
891 unsigned classVecLen
,
892 unsigned funcVecLen
);
895 bool needsInitSProps() const;
897 void importTraitMethod(const TraitMethod
& traitMethod
,
898 const StringData
* methName
,
899 MethodMapBuilder
& curMethodMap
);
900 Class
* findSingleTraitWithMethod(const StringData
* methName
);
901 void setImportTraitMethodModifiers(TraitMethodList
& methList
,
904 void importTraitMethods(MethodMapBuilder
& curMethodMap
);
905 void addTraitPropInitializers(bool staticProps
);
906 void applyTraitRules(MethodToTraitListMap
& importMethToTraitMap
);
907 void applyTraitPrecRule(const PreClass::TraitPrecRule
& rule
,
908 MethodToTraitListMap
& importMethToTraitMap
);
909 void applyTraitAliasRule(const PreClass::TraitAliasRule
& rule
,
910 MethodToTraitListMap
& importMethToTraitMap
);
911 void importTraitProps(int idxOffset
,
912 PropMap::Builder
& curPropMap
,
913 SPropMap::Builder
& curSPropMap
);
914 void importTraitInstanceProp(Class
* trait
,
916 TypedValue
& traitPropVal
,
918 PropMap::Builder
& curPropMap
);
919 void importTraitStaticProp(Class
* trait
,
922 PropMap::Builder
& curPropMap
,
923 SPropMap::Builder
& curSPropMap
);
924 void addTraitAlias(const StringData
* traitName
,
925 const StringData
* origMethName
,
926 const StringData
* newMethName
);
928 void checkInterfaceMethods();
929 void methodOverrideCheck(const Func
* parentMethod
, const Func
* method
);
931 static bool compatibleTraitPropInit(TypedValue
& tv1
, TypedValue
& tv2
);
932 void removeSpareTraitAbstractMethods(
933 MethodToTraitListMap
& importMethToTraitMap
);
938 void setODAttributes();
940 void setProperties();
941 void setInitializers();
942 void setInterfaces();
944 void setFuncVec(MethodMapBuilder
& builder
);
945 void setRequirements();
947 void checkRequirementConstraints() const;
948 void raiseUnsatisfiedRequirement(const PreClass::ClassRequirement
*) const;
949 void setNativeDataInfo();
951 template<bool setParents
> void setInstanceBitsImpl();
952 void addInterfacesFromUsedTraits(InterfaceMap::Builder
& builder
) const;
955 /////////////////////////////////////////////////////////////////////////////
956 // Static data members.
960 * A hashtable that maps class names to structures containing C++ function
961 * pointers for the class's methods and constructors.
963 static hphp_hash_map
<const StringData
*,
964 const HhbcExtClassInfo
*,
966 string_data_isame
> s_extClassHash
;
969 * Callback which, if set, runs during setMethods().
971 static void (*MethodCreateHook
)(Class
* cls
, MethodMapBuilder
& builder
);
974 /////////////////////////////////////////////////////////////////////////////
977 // Ordered by usage frequency. Do not re-order for cosmetic reasons.
979 // The ordering is reverse order of hotness because m_classVec is relatively
980 // hot, and must be the last member.
983 Class
* m_nextClass
{nullptr}; // used by NamedEntity
986 default_ptr
<ExtraData
> m_extra
;
988 RequirementMap m_requirements
;
989 std::unique_ptr
<ClassPtr
[]> m_declInterfaces
;
990 size_t m_numDeclInterfaces
{0};
991 mutable RDS::Link
<Array
> m_nonScalarConstantCache
{RDS::kInvalidHandle
};
993 LowFuncPtr m_toString
;
994 LowFuncPtr m_invoke
; // __invoke, iff non-static (or closure)
996 ConstMap m_constants
;
998 int32_t m_declPropNumAccessible
;
999 mutable RDS::Link
<Class
*> m_cachedClass
{RDS::kInvalidHandle
};
1001 // Vector of 86pinit() methods that need to be called to complete instance
1002 // property initialization, and a pointer to a 86sinit() method that needs to
1003 // be called to complete static property initialization (or NULL). Such
1004 // initialization is triggered only once, the first time one of the following
1006 // - An instance of this class is created.
1007 // - A static property of this class is accessed.
1008 std::vector
<const Func
*> m_sinitVec
;
1011 PropInitVec m_declPropInit
;
1012 std::vector
<const Func
*> m_pinitVec
;
1013 SPropMap m_staticProperties
;
1014 mutable RDS::Link
<PropInitVec
*> m_propDataCache
{RDS::kInvalidHandle
};
1015 PreClassPtr m_preClass
;
1016 InterfaceMap m_interfaces
;
1017 // Bitmap of parent classes and implemented interfaces. Each bit corresponds
1018 // to a commonly used class name, determined during the profiling warmup
1020 InstanceBits::BitSet m_instanceBits
;
1021 MethodMap m_methods
;
1023 // Static properties are stored in RDS. There are three phases of sprop
1025 // 1. The array of links is itself allocated on Class creation.
1026 // 2. The links are bound either when codegen needs the handle value, or when
1027 // initSProps() is called in any request. Afterwards, m_sPropCacheInit is
1028 // bound, defaulting to false.
1029 // 3. The RDS value at m_sPropCacheInit is set to true when initSProps() is
1030 // called, and the values are actually initialized.
1031 mutable RDS::Link
<TypedValue
>* m_sPropCache
{nullptr};
1032 mutable RDS::Link
<bool> m_sPropCacheInit
{RDS::kInvalidHandle
};
1034 unsigned m_classVecLen
;
1035 unsigned m_funcVecLen
;
1037 // Each ObjectData is created with enough trailing space to directly store
1038 // the vector of declared properties. To look up a property by name and
1039 // determine whether it is declared, use m_declPropMap. If the declared
1040 // property index is already known (as may be the case when executing via the
1041 // TC), property metadata in m_declPropInfo can be directly accessed.
1043 // m_declPropInit is indexed by the Slot values from m_declProperties, and
1044 // contains initialization information.
1045 PropMap m_declProperties
;
1047 DataType m_enumBaseTy
;
1050 unsigned m_needInitialization
: 1; // requires initialization,
1051 // due to [ps]init or simply
1052 // having static members
1053 unsigned m_completelyUnused
: 1; // keep things in the same place
1054 unsigned m_callsCustomInstanceInit
: 1; // should we always call __init__
1055 // on new instances?
1056 unsigned m_hasDeepInitProps
: 1;
1057 unsigned m_attrCopy
: 28; // cache of m_preClass->attrs().
1060 * Vector of Class pointers that encodes the inheritance hierarchy, including
1061 * this Class as the last element.
1063 LowClassPtr m_classVec
[1]; // Dynamically sized; must come last.
1066 ///////////////////////////////////////////////////////////////////////////////
1069 * Global lock used during class loading.
1071 extern Mutex g_classesMutex
;
1073 ///////////////////////////////////////////////////////////////////////////////
1076 * Class kinds---classes, interfaces, traits, and enums.
1078 * "Normal class" refers to any classes that are not interfaces, traits, enums.
1080 enum class ClassKind
{
1082 Interface
= AttrInterface
,
1087 Attr
classKindAsAttr(ClassKind kind
);
1089 bool isTrait(const Class
* cls
);
1090 bool isInterface(const Class
* cls
);
1091 bool isEnum(const Class
* cls
);
1092 bool isAbstract(const Class
* cls
);
1093 bool isNormalClass(const Class
* cls
);
1096 * Whether a class is persistent /and/ has a persistent RDS handle. You
1097 * probably mean this instead of cls->isPersistent(), which only checks the
1100 * A persistent class can end up with a non-persistent RDS handle if we had to
1101 * allocate the handle before we loaded the class.
1103 bool classHasPersistentRDS(const Class
* cls
);
1106 * Return the class that "owns" f. This will normally be f->cls(), but for
1107 * Funcs with static locals, f may have been cloned into a derived class.
1109 * @requires: RuntimeOption::EvalPerfDataMap
1111 const Class
* getOwningClassForFunc(const Func
* f
);
1113 ///////////////////////////////////////////////////////////////////////////////
1116 #define incl_HPHP_VM_CLASS_INL_H_
1117 #include "hphp/runtime/vm/class-inl.h"
1118 #undef incl_HPHP_VM_CLASS_INL_H_
1120 #endif // incl_HPHP_VM_CLASS_H_