2 +----------------------------------------------------------------------+
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 +----------------------------------------------------------------------+
17 #include "hphp/util/compilation-flags.h"
19 #include "hphp/runtime/vm/func.h"
23 ///////////////////////////////////////////////////////////////////////////////
25 inline const Func
* ActRec::func() const {
29 inline const Unit
* ActRec::unit() const {
31 return func()->unit();
34 inline ActRec
* ActRec::sfp() const {
35 if (UNLIKELY(((uintptr_t)m_sfp
- s_stackLimit
) < s_stackSize
)) {
41 ///////////////////////////////////////////////////////////////////////////////
43 inline int32_t ActRec::numArgs() const {
44 return m_numArgsAndFlags
& kNumArgsMask
;
47 inline ActRec::Flags
ActRec::flags() const {
48 return static_cast<Flags
>(m_numArgsAndFlags
& kFlagsMask
);
51 inline bool ActRec::useWeakTypes() const {
52 return flags() & UseWeakTypes
;
55 inline bool ActRec::localsDecRefd() const {
56 return flags() & LocalsDecRefd
;
59 inline bool ActRec::resumed() const {
60 return (flags() & kExecutionModeMask
) == InResumed
;
63 inline bool ActRec::isFCallAwait() const {
64 return (flags() & kExecutionModeMask
) == IsFCallAwait
;
67 inline bool ActRec::mayNeedStaticWaitHandle() const {
68 return !(m_numArgsAndFlags
& (InResumed
|IsFCallAwait
));
71 inline bool ActRec::magicDispatch() const {
72 return (flags() & kExecutionModeMask
) == MagicDispatch
;
75 inline uint32_t ActRec::encodeNumArgsAndFlags(uint32_t numArgs
, Flags flags
) {
76 assert((numArgs
& kFlagsMask
) == 0);
77 assert((uint32_t{flags
} & kNumArgsMask
) == 0);
78 return numArgs
| flags
;
81 inline void ActRec::initNumArgs(uint32_t numArgs
) {
82 m_numArgsAndFlags
= encodeNumArgsAndFlags(numArgs
, Flags::None
);
85 inline void ActRec::setNumArgs(uint32_t numArgs
) {
86 m_numArgsAndFlags
= encodeNumArgsAndFlags(numArgs
, flags());
89 inline void ActRec::setUseWeakTypes() {
90 m_numArgsAndFlags
|= UseWeakTypes
;
93 inline void ActRec::setLocalsDecRefd() {
94 m_numArgsAndFlags
|= LocalsDecRefd
;
97 inline void ActRec::setResumed() {
98 assert((flags() & ~IsFCallAwait
) == Flags::None
);
99 m_numArgsAndFlags
= encodeNumArgsAndFlags(numArgs(), InResumed
);
102 inline void ActRec::setFCallAwait() {
103 assert(flags() == Flags::None
);
104 m_numArgsAndFlags
= encodeNumArgsAndFlags(numArgs(), IsFCallAwait
);
107 inline void ActRec::setMagicDispatch(StringData
* invName
) {
109 m_numArgsAndFlags
|= MagicDispatch
;
113 inline StringData
* ActRec::clearMagicDispatch() {
114 assert(magicDispatch());
115 auto const invName
= getInvName();
116 m_numArgsAndFlags
= encodeNumArgsAndFlags(
118 static_cast<Flags
>(flags() & ~MagicDispatch
)
124 ///////////////////////////////////////////////////////////////////////////////
126 inline void* ActRec::encodeThis(ObjectData
* obj
) {
130 inline void* ActRec::encodeClass(const Class
* cls
) {
132 ? (void*)(reinterpret_cast<uintptr_t>(cls
) | kHasClassBit
)
136 inline bool ActRec::checkThis(void* p
) {
138 return !(reinterpret_cast<uintptr_t>(p
) & kHasClassBit
);
141 inline bool ActRec::checkThisOrNull(void* p
) {
142 return !(reinterpret_cast<uintptr_t>(p
) & kHasClassBit
);
145 inline ObjectData
* ActRec::decodeThis(void* p
) {
146 return checkThisOrNull(p
) ? (ObjectData
*)p
: nullptr;
149 inline Class
* ActRec::decodeClass(void* p
) {
150 return checkThisOrNull(p
) ? nullptr :
151 (Class
*)(reinterpret_cast<uintptr_t>(p
) - kHasClassBit
);
154 inline void ActRec::setThisOrClass(void* objOrCls
) {
155 assertx(m_func
->implCls());
156 setThisOrClassAllowNull(objOrCls
);
159 inline void ActRec::setThisOrClassAllowNull(void* objOrCls
) {
160 m_thisUnsafe
= (ObjectData
*)objOrCls
;
163 inline bool ActRec::hasThis() const {
164 assertx(m_func
->implCls());
165 assertx(reinterpret_cast<uintptr_t>(m_thisUnsafe
) != kTrashedThisSlot
);
166 return checkThis(m_thisUnsafe
);
169 inline bool ActRec::hasClass() const {
170 assertx(m_func
->implCls());
171 return !checkThis(m_thisUnsafe
);
174 inline void* ActRec::getThisOrClass() const {
175 assertx(m_func
->implCls());
179 inline ObjectData
* ActRec::getThisUnsafe() const {
183 inline ObjectData
* ActRec::getThis() const {
188 inline Class
* ActRec::getClass() const {
190 return reinterpret_cast<Class
*>(
191 reinterpret_cast<uintptr_t>(m_clsUnsafe
) - kHasClassBit
);
194 inline void ActRec::setThis(ObjectData
* val
) {
195 assertx(m_func
->implCls() && !m_func
->isStaticInPrologue());
199 inline void ActRec::setClass(Class
* val
) {
200 assertx(val
&& m_func
->implCls() && !(m_func
->attrs() & AttrRequiresThis
));
201 m_clsUnsafe
= reinterpret_cast<Class
*>(
202 reinterpret_cast<uintptr_t>(val
) | kHasClassBit
);
205 inline void ActRec::trashThis() {
206 if (debug
) m_thisUnsafe
= reinterpret_cast<ObjectData
*>(kTrashedThisSlot
);
209 /////////////////////////////////////////////////////////////////////////////
211 inline void ActRec::trashVarEnv() {
212 if (debug
) setVarEnv(reinterpret_cast<VarEnv
*>(kTrashedVarEnvSlot
));
215 inline bool ActRec::checkVarEnv() const {
216 assert(m_varEnv
!= reinterpret_cast<VarEnv
*>(kTrashedVarEnvSlot
));
220 inline bool ActRec::hasVarEnv() const {
221 assert(checkVarEnv());
222 assert(!magicDispatch());
223 return m_varEnv
&& !(reinterpret_cast<uintptr_t>(m_varEnv
) & kExtraArgsBit
);
226 inline bool ActRec::hasExtraArgs() const {
227 assert(checkVarEnv());
228 return reinterpret_cast<uintptr_t>(m_extraArgs
) & kExtraArgsBit
;
231 inline VarEnv
* ActRec::getVarEnv() const {
236 inline ExtraArgs
* ActRec::getExtraArgs() const {
237 if (!hasExtraArgs()) return nullptr;
238 return reinterpret_cast<ExtraArgs
*>(
239 reinterpret_cast<uintptr_t>(m_extraArgs
) - kExtraArgsBit
);
242 inline StringData
* ActRec::getInvName() const {
243 assert(magicDispatch());
244 assert(checkVarEnv());
248 inline void ActRec::setVarEnv(VarEnv
* val
) {
252 inline void ActRec::setExtraArgs(ExtraArgs
* val
) {
253 m_extraArgs
= reinterpret_cast<ExtraArgs
*>(
254 reinterpret_cast<uintptr_t>(val
) | kExtraArgsBit
);
257 ///////////////////////////////////////////////////////////////////////////////