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_INL_H_
18 #error "class-inl.h should only be included by class.h"
22 ///////////////////////////////////////////////////////////////////////////////
24 inline bool Class::isZombie() const {
25 return !m_cachedClass
.bound();
28 ///////////////////////////////////////////////////////////////////////////////
29 // Class::PropInitVec.
31 inline Class::PropInitVec::iterator
Class::PropInitVec::begin() {
35 inline Class::PropInitVec::iterator
Class::PropInitVec::end() {
36 return m_data
+ m_size
;
39 inline size_t Class::PropInitVec::size() const {
43 inline TypedValueAux
& Class::PropInitVec::operator[](size_t i
) {
48 inline const TypedValueAux
& Class::PropInitVec::operator[](size_t i
) const {
53 ///////////////////////////////////////////////////////////////////////////////
54 // Pre- and post-allocations.
56 inline const LowClassPtr
* Class::classVec() const {
60 inline unsigned Class::classVecLen() const {
64 ///////////////////////////////////////////////////////////////////////////////
67 inline uint64_t Class::classof(const Class
* cls
) const {
68 // If `cls' is an interface, we can simply check to see if cls is in
69 // this->m_interfaces. Otherwise, if `this' is not an interface, the
70 // classVec check will determine whether it's an instance of cls (including
71 // the case where this and cls are the same trait). Otherwise, `this' is an
72 // interface, and `cls' is not, so we need to return false. But the classVec
73 // check can never return true in that case (cls's classVec contains only
74 // non-interfaces, while this->classVec is either empty, or contains
76 if (UNLIKELY(cls
->attrs() & AttrInterface
)) {
78 m_interfaces
.lookupDefault(cls
->m_preClass
->name(), nullptr) == cls
;
80 if (m_classVecLen
>= cls
->m_classVecLen
) {
81 return (m_classVec
[cls
->m_classVecLen
-1] == cls
);
86 inline bool Class::ifaceofDirect(const StringData
* name
) const {
87 return m_interfaces
.contains(name
);
90 ///////////////////////////////////////////////////////////////////////////////
93 inline const StringData
* Class::name() const {
94 return m_preClass
->name();
97 inline const PreClass
* Class::preClass() const {
98 return m_preClass
.get();
101 inline Class
* Class::parent() const {
102 return m_parent
.get();
105 inline StrNR
Class::nameStr() const {
106 return m_preClass
->nameStr();
109 inline StrNR
Class::parentStr() const {
110 return m_preClass
->parentStr();
113 inline Attr
Class::attrs() const {
114 assert(Attr(m_attrCopy
) == m_preClass
->attrs());
115 return Attr(m_attrCopy
);
118 inline int Class::getODAttrs() const {
122 inline bool Class::isPersistent() const {
123 return attrs() & AttrPersistent
;
126 ///////////////////////////////////////////////////////////////////////////////
129 inline const Func
* Class::getCtor() const {
133 inline const Func
* Class::getDtor() const {
137 inline const Func
* Class::getToString() const {
141 ///////////////////////////////////////////////////////////////////////////////
144 inline bool Class::isBuiltin() const {
145 return attrs() & AttrBuiltin
;
148 inline const ClassInfo
* Class::clsInfo() const {
149 return m_extra
->m_clsInfo
;
152 inline BuiltinCtorFunction
Class::instanceCtor() const {
153 return m_extra
->m_instanceCtor
;
156 inline BuiltinDtorFunction
Class::instanceDtor() const {
157 return m_extra
->m_instanceDtor
;
160 inline int32_t Class::builtinODTailSize() const {
161 return m_extra
->m_builtinODTailSize
;
164 ///////////////////////////////////////////////////////////////////////////////
167 inline size_t Class::numMethods() const {
168 return m_methods
.size();
171 inline Func
* Class::getMethod(Slot idx
) const {
172 auto funcVec
= (LowFuncPtr
*)this;
173 return funcVec
[-((int32_t)idx
+ 1)];
176 inline void Class::setMethod(Slot idx
, Func
* func
) {
177 auto funcVec
= (LowFuncPtr
*)this;
178 funcVec
[-((int32_t)idx
+ 1)] = func
;
181 inline Func
* Class::lookupMethod(const StringData
* methName
) const {
182 Slot
* idx
= m_methods
.find(methName
);
183 if (!idx
) return nullptr;
184 return getMethod(*idx
);
187 ///////////////////////////////////////////////////////////////////////////////
188 // Property metadata.
190 inline size_t Class::numDeclProperties() const {
191 return m_declProperties
.size();
194 inline size_t Class::numStaticProperties() const {
195 return m_staticProperties
.size();
198 inline uint32_t Class::declPropNumAccessible() const {
199 return m_declPropNumAccessible
;
202 inline const Class::Prop
* Class::declProperties() const {
203 return m_declProperties
.accessList();
206 inline const Class::SProp
* Class::staticProperties() const {
207 return m_staticProperties
.accessList();
210 inline Slot
Class::lookupDeclProp(const StringData
* propName
) const {
211 return m_declProperties
.findIndex(propName
);
214 inline Slot
Class::lookupSProp(const StringData
* sPropName
) const {
215 return m_staticProperties
.findIndex(sPropName
);
218 inline RepoAuthType
Class::declPropRepoAuthType(Slot index
) const {
219 return m_declProperties
[index
].m_repoAuthType
;
222 inline RepoAuthType
Class::staticPropRepoAuthType(Slot index
) const {
223 return m_staticProperties
[index
].m_repoAuthType
;
226 inline bool Class::hasDeepInitProps() const {
227 return m_hasDeepInitProps
;
230 ///////////////////////////////////////////////////////////////////////////////
231 // Property initialization.
233 inline bool Class::needInitialization() const {
234 return m_needInitialization
;
237 inline const Class::PropInitVec
& Class::declPropInit() const {
238 return m_declPropInit
;
241 inline const std::vector
<const Func
*>& Class::pinitVec() const {
245 ///////////////////////////////////////////////////////////////////////////////
248 inline void Class::initPropHandle() const {
249 m_propDataCache
.bind();
252 inline RDS::Handle
Class::propHandle() const {
253 return m_propDataCache
.handle();
256 inline RDS::Handle
Class::sPropInitHandle() const {
257 return m_sPropCacheInit
.handle();
260 inline RDS::Handle
Class::sPropHandle(Slot index
) const {
261 assert(m_sPropCacheInit
.bound());
262 assert(numStaticProperties() > index
);
263 return m_sPropCache
[index
].handle();
266 ///////////////////////////////////////////////////////////////////////////////
269 inline size_t Class::numConstants() const {
270 return m_constants
.size();
273 inline const Class::Const
* Class::constants() const {
274 return m_constants
.accessList();
277 inline bool Class::hasConstant(const StringData
* clsCnsName
) const {
278 return m_constants
.contains(clsCnsName
);
281 ///////////////////////////////////////////////////////////////////////////////
282 // Interfaces and traits.
284 inline boost::iterator_range
<const ClassPtr
*> Class::declInterfaces() const {
285 return boost::make_iterator_range(
286 m_declInterfaces
.get(),
287 m_declInterfaces
.get() + m_numDeclInterfaces
291 inline const Class::InterfaceMap
& Class::allInterfaces() const {
295 inline Slot
Class::traitsBeginIdx() const {
296 return m_extra
->m_traitsBeginIdx
;
299 inline Slot
Class::traitsEndIdx() const {
300 return m_extra
->m_traitsEndIdx
;
303 inline const std::vector
<ClassPtr
>& Class::usedTraitClasses() const {
304 return m_extra
->m_usedTraits
;
307 inline const Class::TraitAliasVec
& Class::traitAliases() const {
308 return m_extra
->m_traitAliases
;
311 inline const Class::RequirementMap
& Class::allRequirements() const {
312 return m_requirements
;
315 ///////////////////////////////////////////////////////////////////////////////
318 inline bool Class::callsCustomInstanceInit() const {
319 return m_callsCustomInstanceInit
;
322 ///////////////////////////////////////////////////////////////////////////////
325 inline RDS::Handle
Class::classHandle() const {
326 return m_cachedClass
.handle();
329 inline void Class::setClassHandle(RDS::Link
<Class
*> link
) const {
330 assert(!m_cachedClass
.bound());
331 m_cachedClass
= link
;
334 inline Class
* Class::getCached() const {
335 return *m_cachedClass
;
338 inline void Class::setCached() {
339 *m_cachedClass
= this;
342 inline const Native::NativeDataInfo
* Class::getNativeDataInfo() const {
343 return m_extra
->m_nativeDataInfo
;
346 inline DataType
Class::enumBaseTy() const {
350 ///////////////////////////////////////////////////////////////////////////////
353 inline void Class::allocExtraData() {
355 m_extra
= new ExtraData();
359 ///////////////////////////////////////////////////////////////////////////////
361 inline Attr
classKindAsAttr(ClassKind kind
) {
362 return static_cast<Attr
>(kind
);
365 inline bool isTrait(const Class
* cls
) {
366 return cls
->attrs() & AttrTrait
;
369 inline bool isEnum(const Class
* cls
) {
370 return cls
->attrs() & AttrEnum
;
373 inline bool isInterface(const Class
* cls
) {
374 return cls
->attrs() & AttrInterface
;
377 inline bool isNormalClass(const Class
* cls
) {
378 return !(cls
->attrs() & (AttrTrait
| AttrInterface
| AttrEnum
));
381 inline bool isAbstract(const Class
* cls
) {
382 return cls
->attrs() & AttrAbstract
;
385 inline bool classHasPersistentRDS(const Class
* cls
) {
386 return cls
&& RDS::isPersistentHandle(cls
->classHandle());
389 ///////////////////////////////////////////////////////////////////////////////