2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-2015 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 +----------------------------------------------------------------------+
16 #ifndef incl_HPHP_JIT_STACK_OFFSETS_H_
17 #define incl_HPHP_JIT_STACK_OFFSETS_H_
19 #include "hphp/util/safe-cast.h"
22 * We compute and store 'stack offsets' in many different places in the jit,
23 * and there are a number of different frames of reference for these offsets.
24 * This header declares some structs that allow us to be explicit about which
25 * frame of reference we're using and provides a little bit of type safety when
26 * converting between these various reference frames. Below is a diagram of how
27 * the stack is generally laid out along with an example of what some offsets in
28 * each reference frame refers to.
30 * Stack reference frames:
34 * | ActRec | higher addresses
36 * | ActRec | <--- fp |
42 * | evalslot CC | <--- stkptr |
51 * FPRel: Offset in cells relative to the frame pointer in address order.
52 * FPInv: Offset in cells relative to the frame pointer in reverse address
53 * order (i.e. a positive offset indicates lower address).
54 * IRSP: Offset in cells relative to the IR stack pointer in address order.
55 * BCSP: Offset in cells relative to the top of the stack at the start of the
56 * current bytecode in address order.
58 * Supposing we're translating a bytecode instruction where EE is "top of
59 * stack" in HHBC semantics, then here are some examples:
61 * slot FPRel FPInv IRSP BCSP
70 * NB: The operators that are present in the various offset structs were added on
71 * an as-needed basis. If you find that something obvious is missing, it's
72 * probably because nobody was doing it previously. Do keep in mind, however,
73 * that it doesn't always make sense to add all operators for all offset types.
74 * For example, it doesn't really make sense to add an IRSPOffset and a
75 * BCSPOffset together.
78 namespace HPHP
{ namespace jit
{
83 bool operator==(IRSPOffset o
) const { return offset
== o
.offset
; }
84 bool operator==(int32_t other
) const { return offset
== other
; }
86 IRSPOffset
operator+(int32_t x
) const { return IRSPOffset
{offset
+ x
}; }
87 IRSPOffset
operator-(int32_t x
) const { return IRSPOffset
{offset
- x
}; }
89 bool operator<(IRSPOffset o
) const { return offset
< o
.offset
; }
90 bool operator>(IRSPOffset o
) const { return offset
> o
.offset
; }
92 IRSPOffset
& operator+=(size_t delta
) {
98 inline IRSPOffset
operator+(int32_t lhs
, IRSPOffset rhs
) {
101 inline IRSPOffset
operator-(int32_t lhs
, IRSPOffset rhs
) {
102 return IRSPOffset
{lhs
- rhs
.offset
};
108 bool operator==(BCSPOffset o
) const { return offset
== o
.offset
; }
109 bool operator==(int32_t otherOffset
) const { return offset
== otherOffset
; }
110 bool operator>=(int32_t otherOffset
) const { return offset
>= otherOffset
; }
111 bool operator<(BCSPOffset other
) const { return offset
< other
.offset
; }
112 bool operator>(BCSPOffset other
) const { return offset
> other
.offset
; }
113 bool operator<(int32_t otherOffset
) const { return offset
< otherOffset
; }
115 BCSPOffset
& operator++() {
120 BCSPOffset
operator++(int) {
121 auto before
= BCSPOffset
{offset
};
126 BCSPOffset
& operator+=(size_t delta
) {
127 offset
+= safe_cast
<int32_t>(delta
);
131 BCSPOffset
operator-() const { return BCSPOffset
{-offset
}; }
133 BCSPOffset
operator-(int32_t delta
) { return BCSPOffset
{offset
- delta
}; }
139 static constexpr FPInvOffset
invalid() { return FPInvOffset
{INT_MIN
}; }
141 bool operator==(FPInvOffset o
) const { return offset
== o
.offset
; }
143 bool isValid() const {
144 return offset
!= INT_MIN
;
147 FPInvOffset
operator+(int32_t delta
) const {
148 return FPInvOffset
{offset
+ delta
};
151 // Return an int32_t because the difference between two FPInvOffsets is no
152 // longer an FPInvOffset.
153 int32_t operator-(FPInvOffset o
) const { return offset
- o
.offset
; }
154 FPInvOffset
operator-(BCSPOffset o
) const {
155 return FPInvOffset
{offset
- o
.offset
};
157 FPInvOffset
operator-(IRSPOffset o
) {
158 return FPInvOffset
{offset
- o
.offset
};
160 FPInvOffset
operator-(int32_t delta
) const {
161 return FPInvOffset
{offset
- delta
};
164 FPInvOffset
& operator++() {
169 FPInvOffset
& operator--() {
174 FPInvOffset
& operator+=(int32_t delta
) {
178 FPInvOffset
& operator-=(int32_t delta
) {
183 bool operator>(FPInvOffset o
) const { return offset
> o
.offset
; }
184 bool operator>(int32_t otherOffset
) const { return offset
> otherOffset
; }
185 bool operator>=(int32_t otherOffset
) const { return offset
>= otherOffset
; }
186 bool operator<(FPInvOffset other
) const { return offset
< other
.offset
; }
187 bool operator<(int32_t otherOffset
) const { return offset
< otherOffset
; }
190 inline bool operator>=(size_t lhs
, FPInvOffset rhs
) {
191 return safe_cast
<int32_t>(lhs
) >= rhs
.offset
;
197 FPRelOffset
operator+(int32_t x
) const { return FPRelOffset
{offset
+ x
}; }
198 FPRelOffset
operator-(int32_t x
) const { return FPRelOffset
{offset
- x
}; }
201 inline FPRelOffset
operator+(int32_t lhs
, FPRelOffset rhs
) {
207 #endif // incl_HPHP_JIT_STACK_OFFSETS_H_