2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010- 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_TRANSLATOR_INLINE_H_
18 #define incl_HPHP_TRANSLATOR_INLINE_H_
20 #include "hphp/runtime/vm/translator/translator.h"
21 #include <boost/noncopyable.hpp>
22 #include "hphp/runtime/base/execution_context.h"
24 #define TVOFF(nm) offsetof(TypedValue, nm)
25 #define AROFF(nm) offsetof(ActRec, nm)
28 * Because of a circular dependence with ExecutionContext, these
29 * translation-related helpers cannot live in translator.h.
34 * Accessors for the virtual machine registers, both rvalues and
37 * Note that these do not assert anything about tl_regState; use
40 static inline Cell
*& vmsp() { return (Cell
*&)g_vmContext
->m_stack
.top(); }
41 static inline Cell
*& vmfp() { return (Cell
*&)g_vmContext
->m_fp
; }
42 static inline const uchar
*& vmpc() { return g_vmContext
->m_pc
; }
43 static inline ActRec
*& vmFirstAR() { return g_vmContext
->m_firstAR
; }
45 static inline ActRec
* curFrame() { return (ActRec
*)vmfp(); }
46 static inline const Func
* curFunc() { return curFrame()->m_func
; }
47 static inline const Unit
* curUnit() { return curFunc()->unit(); }
48 static inline Class
* curClass() {
49 const auto* func
= curFunc();
50 auto* cls
= func
->cls();
51 if (func
->isPseudoMain() || func
->isTraitMethod() || cls
== nullptr) {
59 static inline uintptr_t tlsBase() {
61 #if defined(__x86_64__)
62 asm ("movq %%fs:0, %0" : "=r" (retval
));
63 #elif defined(__AARCH64EL__)
64 // mrs == "move register <-- system"
65 // tpidr_el0 == "thread process id register for exception level 0"
66 asm ("mrs %0, tpidr_el0" : "=r" (retval
));
68 # error How do you access thread-local storage on this machine?
73 static inline int cellsToBytes(int nCells
) {
74 return nCells
* sizeof(Cell
);
77 static inline size_t bytesToCells(int nBytes
) {
78 assert(nBytes
% sizeof(Cell
) == 0);
79 return nBytes
/ sizeof(Cell
);
82 struct VMRegAnchor
: private boost::noncopyable
{
86 DEBUG_ONLY
DECLARE_STACK_POINTER(sp
);
87 // native stack pointer should be octoword-aligned.
88 assert((uintptr_t(sp
) & 0xf) == 0);
91 Translator::Get()->sync();
93 explicit VMRegAnchor(ActRec
* ar
) {
94 // Some C++ entry points have an ActRec prepared from after a call
95 // instruction. This syncs us to right after the call instruction.
96 assert(tl_regState
== REGSTATE_DIRTY
);
97 m_old
= REGSTATE_DIRTY
;
98 tl_regState
= REGSTATE_CLEAN
;
100 auto prevAr
= g_vmContext
->getOuterVMFrame(ar
);
101 const Func
* prevF
= prevAr
->m_func
;
102 vmsp() = ar
->m_func
->isGenerator() ?
103 Stack::generatorStackBase(ar
) :
104 (TypedValue
*)ar
- ar
->numArgs();
105 assert(g_vmContext
->m_stack
.isValidAddress((uintptr_t)vmsp()));
106 vmpc() = prevF
->unit()->at(prevF
->base() + ar
->m_soff
);
107 vmfp() = (TypedValue
*)prevAr
;
114 // VM helper to retrieve the frame pointer from the TC. This is
115 // a common need for extensions.
116 struct CallerFrame
: public VMRegAnchor
{
117 ActRec
* operator()() {
118 // In builtins, m_fp points to the caller's frame if called
119 // through FCallBuiltin, else it points to the builtin's frame,
120 // in which case, getPrevVMState() gets the caller's frame.
121 VMExecutionContext
* context
= g_vmContext
;
122 ActRec
* cur
= context
->getFP();
123 if (!cur
) return nullptr;
124 if (cur
->skipFrame()) {
125 ActRec
* prev
= context
->getPrevVMState(cur
);
126 if (prev
== cur
) return nullptr;
134 #define SYNC_VM_REGS_SCOPED() \
135 HPHP::Transl::VMRegAnchor _anchorUnused