make #includes consistent
[hiphop-php.git] / hphp / runtime / vm / translator / translator-inline.h
blob0c03533757cf80e342a32286d439f3fd1f99300b
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
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.
31 namespace HPHP {
34 * Accessors for the virtual machine registers, both rvalues and
35 * lvalues.
37 * Note that these do not assert anything about tl_regState; use
38 * carefully.
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) {
52 return nullptr;
54 return cls;
57 namespace Transl {
59 static inline uintptr_t tlsBase() {
60 uintptr_t retval;
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));
67 #else
68 # error How do you access thread-local storage on this machine?
69 #endif
70 return retval;
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 {
83 VMRegState m_old;
84 VMRegAnchor() {
85 if (debug) {
86 DEBUG_ONLY DECLARE_STACK_POINTER(sp);
87 // native stack pointer should be octoword-aligned.
88 assert((uintptr_t(sp) & 0xf) == 0);
90 m_old = tl_regState;
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;
109 ~VMRegAnchor() {
110 tl_regState = m_old;
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;
127 return prev;
128 } else {
129 return cur;
134 #define SYNC_VM_REGS_SCOPED() \
135 HPHP::Transl::VMRegAnchor _anchorUnused
137 } } // HPHP::Transl
139 #endif