| 1 | /* | 
|---|
| 2 | ** Stack frames. | 
|---|
| 3 | ** Copyright (C) 2005-2021 Mike Pall. See Copyright Notice in luajit.h | 
|---|
| 4 | */ | 
|---|
| 5 |  | 
|---|
| 6 | #ifndef _LJ_FRAME_H | 
|---|
| 7 | #define _LJ_FRAME_H | 
|---|
| 8 |  | 
|---|
| 9 | #include "lj_obj.h" | 
|---|
| 10 | #include "lj_bc.h" | 
|---|
| 11 |  | 
|---|
| 12 | /* -- Lua stack frame ----------------------------------------------------- */ | 
|---|
| 13 |  | 
|---|
| 14 | /* Frame type markers in LSB of PC (4-byte aligned) or delta (8-byte aligned: | 
|---|
| 15 | ** | 
|---|
| 16 | **    PC  00  Lua frame | 
|---|
| 17 | ** delta 001  C frame | 
|---|
| 18 | ** delta 010  Continuation frame | 
|---|
| 19 | ** delta 011  Lua vararg frame | 
|---|
| 20 | ** delta 101  cpcall() frame | 
|---|
| 21 | ** delta 110  ff pcall() frame | 
|---|
| 22 | ** delta 111  ff pcall() frame with active hook | 
|---|
| 23 | */ | 
|---|
| 24 | enum { | 
|---|
| 25 | FRAME_LUA, FRAME_C, FRAME_CONT, FRAME_VARG, | 
|---|
| 26 | FRAME_LUAP, FRAME_CP, FRAME_PCALL, FRAME_PCALLH | 
|---|
| 27 | }; | 
|---|
| 28 | #define FRAME_TYPE		3 | 
|---|
| 29 | #define FRAME_P			4 | 
|---|
| 30 | #define FRAME_TYPEP		(FRAME_TYPE|FRAME_P) | 
|---|
| 31 |  | 
|---|
| 32 | /* Macros to access and modify Lua frames. */ | 
|---|
| 33 | #if LJ_FR2 | 
|---|
| 34 | /* Two-slot frame info, required for 64 bit PC/GCRef: | 
|---|
| 35 | ** | 
|---|
| 36 | **                   base-2  base-1      |  base  base+1 ... | 
|---|
| 37 | **                  [func   PC/delta/ft] | [slots ...] | 
|---|
| 38 | **                  ^-- frame            | ^-- base   ^-- top | 
|---|
| 39 | ** | 
|---|
| 40 | ** Continuation frames: | 
|---|
| 41 | ** | 
|---|
| 42 | **   base-4  base-3  base-2  base-1      |  base  base+1 ... | 
|---|
| 43 | **  [cont      PC ] [func   PC/delta/ft] | [slots ...] | 
|---|
| 44 | **                  ^-- frame            | ^-- base   ^-- top | 
|---|
| 45 | */ | 
|---|
| 46 | #define frame_gc(f)		(gcval((f)-1)) | 
|---|
| 47 | #define frame_ftsz(f)		((ptrdiff_t)(f)->ftsz) | 
|---|
| 48 | #define frame_pc(f)		((const BCIns *)frame_ftsz(f)) | 
|---|
| 49 | #define setframe_gc(f, p, tp)	(setgcVraw((f), (p), (tp))) | 
|---|
| 50 | #define setframe_ftsz(f, sz)	((f)->ftsz = (sz)) | 
|---|
| 51 | #define setframe_pc(f, pc)	((f)->ftsz = (int64_t)(intptr_t)(pc)) | 
|---|
| 52 | #else | 
|---|
| 53 | /* One-slot frame info, sufficient for 32 bit PC/GCRef: | 
|---|
| 54 | ** | 
|---|
| 55 | **              base-1              |  base  base+1 ... | 
|---|
| 56 | **              lo     hi           | | 
|---|
| 57 | **             [func | PC/delta/ft] | [slots ...] | 
|---|
| 58 | **             ^-- frame            | ^-- base   ^-- top | 
|---|
| 59 | ** | 
|---|
| 60 | ** Continuation frames: | 
|---|
| 61 | ** | 
|---|
| 62 | **  base-2      base-1              |  base  base+1 ... | 
|---|
| 63 | **  lo     hi   lo     hi           | | 
|---|
| 64 | ** [cont | PC] [func | PC/delta/ft] | [slots ...] | 
|---|
| 65 | **             ^-- frame            | ^-- base   ^-- top | 
|---|
| 66 | */ | 
|---|
| 67 | #define frame_gc(f)		(gcref((f)->fr.func)) | 
|---|
| 68 | #define frame_ftsz(f)		((ptrdiff_t)(f)->fr.tp.ftsz) | 
|---|
| 69 | #define frame_pc(f)		(mref((f)->fr.tp.pcr, const BCIns)) | 
|---|
| 70 | #define setframe_gc(f, p, tp)	(setgcref((f)->fr.func, (p)), UNUSED(tp)) | 
|---|
| 71 | #define setframe_ftsz(f, sz)	((f)->fr.tp.ftsz = (int32_t)(sz)) | 
|---|
| 72 | #define setframe_pc(f, pc)	(setmref((f)->fr.tp.pcr, (pc))) | 
|---|
| 73 | #endif | 
|---|
| 74 |  | 
|---|
| 75 | #define frame_type(f)		(frame_ftsz(f) & FRAME_TYPE) | 
|---|
| 76 | #define frame_typep(f)		(frame_ftsz(f) & FRAME_TYPEP) | 
|---|
| 77 | #define frame_islua(f)		(frame_type(f) == FRAME_LUA) | 
|---|
| 78 | #define frame_isc(f)		(frame_type(f) == FRAME_C) | 
|---|
| 79 | #define frame_iscont(f)		(frame_typep(f) == FRAME_CONT) | 
|---|
| 80 | #define frame_isvarg(f)		(frame_typep(f) == FRAME_VARG) | 
|---|
| 81 | #define frame_ispcall(f)	((frame_ftsz(f) & 6) == FRAME_PCALL) | 
|---|
| 82 |  | 
|---|
| 83 | #define frame_func(f)		(&frame_gc(f)->fn) | 
|---|
| 84 | #define frame_delta(f)		(frame_ftsz(f) >> 3) | 
|---|
| 85 | #define frame_sized(f)		(frame_ftsz(f) & ~FRAME_TYPEP) | 
|---|
| 86 |  | 
|---|
| 87 | enum { LJ_CONT_TAILCALL, LJ_CONT_FFI_CALLBACK };  /* Special continuations. */ | 
|---|
| 88 |  | 
|---|
| 89 | #if LJ_FR2 | 
|---|
| 90 | #define frame_contpc(f)		(frame_pc((f)-2)) | 
|---|
| 91 | #define frame_contv(f)		(((f)-3)->u64) | 
|---|
| 92 | #else | 
|---|
| 93 | #define frame_contpc(f)		(frame_pc((f)-1)) | 
|---|
| 94 | #define frame_contv(f)		(((f)-1)->u32.lo) | 
|---|
| 95 | #endif | 
|---|
| 96 | #if LJ_FR2 | 
|---|
| 97 | #define frame_contf(f)		((ASMFunction)(uintptr_t)((f)-3)->u64) | 
|---|
| 98 | #elif LJ_64 | 
|---|
| 99 | #define frame_contf(f) \ | 
|---|
| 100 | ((ASMFunction)(void *)((intptr_t)lj_vm_asm_begin + \ | 
|---|
| 101 | (intptr_t)(int32_t)((f)-1)->u32.lo)) | 
|---|
| 102 | #else | 
|---|
| 103 | #define frame_contf(f)		((ASMFunction)gcrefp(((f)-1)->gcr, void)) | 
|---|
| 104 | #endif | 
|---|
| 105 | #define frame_iscont_fficb(f) \ | 
|---|
| 106 | (LJ_HASFFI && frame_contv(f) == LJ_CONT_FFI_CALLBACK) | 
|---|
| 107 |  | 
|---|
| 108 | #define frame_prevl(f)		((f) - (1+LJ_FR2+bc_a(frame_pc(f)[-1]))) | 
|---|
| 109 | #define frame_prevd(f)		((TValue *)((char *)(f) - frame_sized(f))) | 
|---|
| 110 | #define frame_prev(f)		(frame_islua(f)?frame_prevl(f):frame_prevd(f)) | 
|---|
| 111 | /* Note: this macro does not skip over FRAME_VARG. */ | 
|---|
| 112 |  | 
|---|
| 113 | /* -- C stack frame ------------------------------------------------------- */ | 
|---|
| 114 |  | 
|---|
| 115 | /* Macros to access and modify the C stack frame chain. */ | 
|---|
| 116 |  | 
|---|
| 117 | /* These definitions must match with the arch-specific *.dasc files. */ | 
|---|
| 118 | #if LJ_TARGET_X86 | 
|---|
| 119 | #if LJ_ABI_WIN | 
|---|
| 120 | #define CFRAME_OFS_ERRF		(19*4) | 
|---|
| 121 | #define CFRAME_OFS_NRES		(18*4) | 
|---|
| 122 | #define CFRAME_OFS_PREV		(17*4) | 
|---|
| 123 | #define CFRAME_OFS_L		(16*4) | 
|---|
| 124 | #define CFRAME_OFS_SEH		(9*4) | 
|---|
| 125 | #define CFRAME_OFS_PC		(6*4) | 
|---|
| 126 | #define CFRAME_OFS_MULTRES	(5*4) | 
|---|
| 127 | #define CFRAME_SIZE		(16*4) | 
|---|
| 128 | #define CFRAME_SHIFT_MULTRES	0 | 
|---|
| 129 | #else | 
|---|
| 130 | #define CFRAME_OFS_ERRF		(15*4) | 
|---|
| 131 | #define CFRAME_OFS_NRES		(14*4) | 
|---|
| 132 | #define CFRAME_OFS_PREV		(13*4) | 
|---|
| 133 | #define CFRAME_OFS_L		(12*4) | 
|---|
| 134 | #define CFRAME_OFS_PC		(6*4) | 
|---|
| 135 | #define CFRAME_OFS_MULTRES	(5*4) | 
|---|
| 136 | #define CFRAME_SIZE		(12*4) | 
|---|
| 137 | #define CFRAME_SHIFT_MULTRES	0 | 
|---|
| 138 | #endif | 
|---|
| 139 | #elif LJ_TARGET_X64 | 
|---|
| 140 | #if LJ_ABI_WIN | 
|---|
| 141 | #define CFRAME_OFS_PREV		(13*8) | 
|---|
| 142 | #if LJ_GC64 | 
|---|
| 143 | #define CFRAME_OFS_PC		(12*8) | 
|---|
| 144 | #define CFRAME_OFS_L		(11*8) | 
|---|
| 145 | #define CFRAME_OFS_ERRF		(21*4) | 
|---|
| 146 | #define CFRAME_OFS_NRES		(20*4) | 
|---|
| 147 | #define CFRAME_OFS_MULTRES	(8*4) | 
|---|
| 148 | #else | 
|---|
| 149 | #define CFRAME_OFS_PC		(25*4) | 
|---|
| 150 | #define CFRAME_OFS_L		(24*4) | 
|---|
| 151 | #define CFRAME_OFS_ERRF		(23*4) | 
|---|
| 152 | #define CFRAME_OFS_NRES		(22*4) | 
|---|
| 153 | #define CFRAME_OFS_MULTRES	(21*4) | 
|---|
| 154 | #endif | 
|---|
| 155 | #define CFRAME_SIZE		(10*8) | 
|---|
| 156 | #define CFRAME_SIZE_JIT		(CFRAME_SIZE + 9*16 + 4*8) | 
|---|
| 157 | #define CFRAME_SHIFT_MULTRES	0 | 
|---|
| 158 | #else | 
|---|
| 159 | #define CFRAME_OFS_PREV		(4*8) | 
|---|
| 160 | #if LJ_GC64 | 
|---|
| 161 | #define CFRAME_OFS_PC		(3*8) | 
|---|
| 162 | #define CFRAME_OFS_L		(2*8) | 
|---|
| 163 | #define CFRAME_OFS_ERRF		(3*4) | 
|---|
| 164 | #define CFRAME_OFS_NRES		(2*4) | 
|---|
| 165 | #define CFRAME_OFS_MULTRES	(0*4) | 
|---|
| 166 | #else | 
|---|
| 167 | #define CFRAME_OFS_PC		(7*4) | 
|---|
| 168 | #define CFRAME_OFS_L		(6*4) | 
|---|
| 169 | #define CFRAME_OFS_ERRF		(5*4) | 
|---|
| 170 | #define CFRAME_OFS_NRES		(4*4) | 
|---|
| 171 | #define CFRAME_OFS_MULTRES	(1*4) | 
|---|
| 172 | #endif | 
|---|
| 173 | #if LJ_NO_UNWIND | 
|---|
| 174 | #define CFRAME_SIZE		(12*8) | 
|---|
| 175 | #else | 
|---|
| 176 | #define CFRAME_SIZE		(10*8) | 
|---|
| 177 | #endif | 
|---|
| 178 | #define CFRAME_SIZE_JIT		(CFRAME_SIZE + 16) | 
|---|
| 179 | #define CFRAME_SHIFT_MULTRES	0 | 
|---|
| 180 | #endif | 
|---|
| 181 | #elif LJ_TARGET_ARM | 
|---|
| 182 | #define CFRAME_OFS_ERRF		24 | 
|---|
| 183 | #define CFRAME_OFS_NRES		20 | 
|---|
| 184 | #define CFRAME_OFS_PREV		16 | 
|---|
| 185 | #define CFRAME_OFS_L		12 | 
|---|
| 186 | #define CFRAME_OFS_PC		8 | 
|---|
| 187 | #define CFRAME_OFS_MULTRES	4 | 
|---|
| 188 | #if LJ_ARCH_HASFPU | 
|---|
| 189 | #define CFRAME_SIZE		128 | 
|---|
| 190 | #else | 
|---|
| 191 | #define CFRAME_SIZE		64 | 
|---|
| 192 | #endif | 
|---|
| 193 | #define CFRAME_SHIFT_MULTRES	3 | 
|---|
| 194 | #elif LJ_TARGET_ARM64 | 
|---|
| 195 | #define CFRAME_OFS_ERRF		196 | 
|---|
| 196 | #define CFRAME_OFS_NRES		200 | 
|---|
| 197 | #define CFRAME_OFS_PREV		160 | 
|---|
| 198 | #define CFRAME_OFS_L		176 | 
|---|
| 199 | #define CFRAME_OFS_PC		168 | 
|---|
| 200 | #define CFRAME_OFS_MULTRES	192 | 
|---|
| 201 | #define CFRAME_SIZE		208 | 
|---|
| 202 | #define CFRAME_SHIFT_MULTRES	3 | 
|---|
| 203 | #elif LJ_TARGET_PPC | 
|---|
| 204 | #if LJ_TARGET_XBOX360 | 
|---|
| 205 | #define CFRAME_OFS_ERRF		424 | 
|---|
| 206 | #define CFRAME_OFS_NRES		420 | 
|---|
| 207 | #define CFRAME_OFS_PREV		400 | 
|---|
| 208 | #define CFRAME_OFS_L		416 | 
|---|
| 209 | #define CFRAME_OFS_PC		412 | 
|---|
| 210 | #define CFRAME_OFS_MULTRES	408 | 
|---|
| 211 | #define CFRAME_SIZE		384 | 
|---|
| 212 | #define CFRAME_SHIFT_MULTRES	3 | 
|---|
| 213 | #elif LJ_ARCH_PPC32ON64 | 
|---|
| 214 | #define CFRAME_OFS_ERRF		472 | 
|---|
| 215 | #define CFRAME_OFS_NRES		468 | 
|---|
| 216 | #define CFRAME_OFS_PREV		448 | 
|---|
| 217 | #define CFRAME_OFS_L		464 | 
|---|
| 218 | #define CFRAME_OFS_PC		460 | 
|---|
| 219 | #define CFRAME_OFS_MULTRES	456 | 
|---|
| 220 | #define CFRAME_SIZE		400 | 
|---|
| 221 | #define CFRAME_SHIFT_MULTRES	3 | 
|---|
| 222 | #else | 
|---|
| 223 | #define CFRAME_OFS_ERRF		48 | 
|---|
| 224 | #define CFRAME_OFS_NRES		44 | 
|---|
| 225 | #define CFRAME_OFS_PREV		40 | 
|---|
| 226 | #define CFRAME_OFS_L		36 | 
|---|
| 227 | #define CFRAME_OFS_PC		32 | 
|---|
| 228 | #define CFRAME_OFS_MULTRES	28 | 
|---|
| 229 | #define CFRAME_SIZE		(LJ_ARCH_HASFPU ? 272 : 128) | 
|---|
| 230 | #define CFRAME_SHIFT_MULTRES	3 | 
|---|
| 231 | #endif | 
|---|
| 232 | #elif LJ_TARGET_MIPS32 | 
|---|
| 233 | #if LJ_ARCH_HASFPU | 
|---|
| 234 | #define CFRAME_OFS_ERRF		124 | 
|---|
| 235 | #define CFRAME_OFS_NRES		120 | 
|---|
| 236 | #define CFRAME_OFS_PREV		116 | 
|---|
| 237 | #define CFRAME_OFS_L		112 | 
|---|
| 238 | #define CFRAME_SIZE		112 | 
|---|
| 239 | #else | 
|---|
| 240 | #define CFRAME_OFS_ERRF		76 | 
|---|
| 241 | #define CFRAME_OFS_NRES		72 | 
|---|
| 242 | #define CFRAME_OFS_PREV		68 | 
|---|
| 243 | #define CFRAME_OFS_L		64 | 
|---|
| 244 | #define CFRAME_SIZE		64 | 
|---|
| 245 | #endif | 
|---|
| 246 | #define CFRAME_OFS_PC		20 | 
|---|
| 247 | #define CFRAME_OFS_MULTRES	16 | 
|---|
| 248 | #define CFRAME_SHIFT_MULTRES	3 | 
|---|
| 249 | #elif LJ_TARGET_MIPS64 | 
|---|
| 250 | #if LJ_ARCH_HASFPU | 
|---|
| 251 | #define CFRAME_OFS_ERRF		188 | 
|---|
| 252 | #define CFRAME_OFS_NRES		184 | 
|---|
| 253 | #define CFRAME_OFS_PREV		176 | 
|---|
| 254 | #define CFRAME_OFS_L		168 | 
|---|
| 255 | #define CFRAME_OFS_PC		160 | 
|---|
| 256 | #define CFRAME_SIZE		192 | 
|---|
| 257 | #else | 
|---|
| 258 | #define CFRAME_OFS_ERRF		124 | 
|---|
| 259 | #define CFRAME_OFS_NRES		120 | 
|---|
| 260 | #define CFRAME_OFS_PREV		112 | 
|---|
| 261 | #define CFRAME_OFS_L		104 | 
|---|
| 262 | #define CFRAME_OFS_PC		96 | 
|---|
| 263 | #define CFRAME_SIZE		128 | 
|---|
| 264 | #endif | 
|---|
| 265 | #define CFRAME_OFS_MULTRES	0 | 
|---|
| 266 | #define CFRAME_SHIFT_MULTRES	3 | 
|---|
| 267 | #else | 
|---|
| 268 | #error "Missing CFRAME_* definitions for this architecture" | 
|---|
| 269 | #endif | 
|---|
| 270 |  | 
|---|
| 271 | #ifndef CFRAME_SIZE_JIT | 
|---|
| 272 | #define CFRAME_SIZE_JIT		CFRAME_SIZE | 
|---|
| 273 | #endif | 
|---|
| 274 |  | 
|---|
| 275 | #define CFRAME_RESUME		1 | 
|---|
| 276 | #define CFRAME_UNWIND_FF	2  /* Only used in unwinder. */ | 
|---|
| 277 | #define CFRAME_RAWMASK		(~(intptr_t)(CFRAME_RESUME|CFRAME_UNWIND_FF)) | 
|---|
| 278 |  | 
|---|
| 279 | #define cframe_errfunc(cf)	(*(int32_t *)(((char *)(cf))+CFRAME_OFS_ERRF)) | 
|---|
| 280 | #define cframe_nres(cf)		(*(int32_t *)(((char *)(cf))+CFRAME_OFS_NRES)) | 
|---|
| 281 | #define cframe_prev(cf)		(*(void **)(((char *)(cf))+CFRAME_OFS_PREV)) | 
|---|
| 282 | #define cframe_multres(cf)  (*(uint32_t *)(((char *)(cf))+CFRAME_OFS_MULTRES)) | 
|---|
| 283 | #define cframe_multres_n(cf)	(cframe_multres((cf)) >> CFRAME_SHIFT_MULTRES) | 
|---|
| 284 | #define cframe_L(cf) \ | 
|---|
| 285 | (&gcref(*(GCRef *)(((char *)(cf))+CFRAME_OFS_L))->th) | 
|---|
| 286 | #define cframe_pc(cf) \ | 
|---|
| 287 | (mref(*(MRef *)(((char *)(cf))+CFRAME_OFS_PC), const BCIns)) | 
|---|
| 288 | #define setcframe_L(cf, L) \ | 
|---|
| 289 | (setmref(*(MRef *)(((char *)(cf))+CFRAME_OFS_L), (L))) | 
|---|
| 290 | #define setcframe_pc(cf, pc) \ | 
|---|
| 291 | (setmref(*(MRef *)(((char *)(cf))+CFRAME_OFS_PC), (pc))) | 
|---|
| 292 | #define cframe_canyield(cf)	((intptr_t)(cf) & CFRAME_RESUME) | 
|---|
| 293 | #define cframe_unwind_ff(cf)	((intptr_t)(cf) & CFRAME_UNWIND_FF) | 
|---|
| 294 | #define cframe_raw(cf)		((void *)((intptr_t)(cf) & CFRAME_RAWMASK)) | 
|---|
| 295 | #define cframe_Lpc(L)		cframe_pc(cframe_raw(L->cframe)) | 
|---|
| 296 |  | 
|---|
| 297 | #endif | 
|---|
| 298 |  | 
|---|