Mercurial
comparison third_party/luajit/src/lj_def.h @ 186:8cf4ec5e2191 hg-web
Fixed merge conflict.
| author | MrJuneJune <me@mrjunejune.com> |
|---|---|
| date | Fri, 23 Jan 2026 22:38:59 -0800 |
| parents | 94705b5986b3 |
| children |
comparison
equal
deleted
inserted
replaced
| 176:fed99fc04e12 | 186:8cf4ec5e2191 |
|---|---|
| 1 /* | |
| 2 ** LuaJIT common internal definitions. | |
| 3 ** Copyright (C) 2005-2023 Mike Pall. See Copyright Notice in luajit.h | |
| 4 */ | |
| 5 | |
| 6 #ifndef _LJ_DEF_H | |
| 7 #define _LJ_DEF_H | |
| 8 | |
| 9 #include "lua.h" | |
| 10 | |
| 11 #if defined(_MSC_VER) && (_MSC_VER < 1700) | |
| 12 /* Old MSVC is stuck in the last century and doesn't have C99's stdint.h. */ | |
| 13 typedef __int8 int8_t; | |
| 14 typedef __int16 int16_t; | |
| 15 typedef __int32 int32_t; | |
| 16 typedef __int64 int64_t; | |
| 17 typedef unsigned __int8 uint8_t; | |
| 18 typedef unsigned __int16 uint16_t; | |
| 19 typedef unsigned __int32 uint32_t; | |
| 20 typedef unsigned __int64 uint64_t; | |
| 21 #ifdef _WIN64 | |
| 22 typedef __int64 intptr_t; | |
| 23 typedef unsigned __int64 uintptr_t; | |
| 24 #else | |
| 25 typedef __int32 intptr_t; | |
| 26 typedef unsigned __int32 uintptr_t; | |
| 27 #endif | |
| 28 #elif defined(__symbian__) | |
| 29 /* Cough. */ | |
| 30 typedef signed char int8_t; | |
| 31 typedef short int int16_t; | |
| 32 typedef int int32_t; | |
| 33 typedef long long int64_t; | |
| 34 typedef unsigned char uint8_t; | |
| 35 typedef unsigned short int uint16_t; | |
| 36 typedef unsigned int uint32_t; | |
| 37 typedef unsigned long long uint64_t; | |
| 38 typedef int intptr_t; | |
| 39 typedef unsigned int uintptr_t; | |
| 40 #else | |
| 41 #include <stdint.h> | |
| 42 #endif | |
| 43 | |
| 44 /* Needed everywhere. */ | |
| 45 #include <string.h> | |
| 46 #include <stdlib.h> | |
| 47 | |
| 48 /* Various VM limits. */ | |
| 49 #define LJ_MAX_MEM32 0x7fffff00 /* Max. 32 bit memory allocation. */ | |
| 50 #define LJ_MAX_MEM64 ((uint64_t)1<<47) /* Max. 64 bit memory allocation. */ | |
| 51 /* Max. total memory allocation. */ | |
| 52 #define LJ_MAX_MEM (LJ_GC64 ? LJ_MAX_MEM64 : LJ_MAX_MEM32) | |
| 53 #define LJ_MAX_ALLOC LJ_MAX_MEM /* Max. individual allocation length. */ | |
| 54 #define LJ_MAX_STR LJ_MAX_MEM32 /* Max. string length. */ | |
| 55 #define LJ_MAX_BUF LJ_MAX_MEM32 /* Max. buffer length. */ | |
| 56 #define LJ_MAX_UDATA LJ_MAX_MEM32 /* Max. userdata length. */ | |
| 57 | |
| 58 #define LJ_MAX_STRTAB (1<<26) /* Max. string table size. */ | |
| 59 #define LJ_MAX_HBITS 26 /* Max. hash bits. */ | |
| 60 #define LJ_MAX_ABITS 28 /* Max. bits of array key. */ | |
| 61 #define LJ_MAX_ASIZE ((1<<(LJ_MAX_ABITS-1))+1) /* Max. array part size. */ | |
| 62 #define LJ_MAX_COLOSIZE 16 /* Max. elems for colocated array. */ | |
| 63 | |
| 64 #define LJ_MAX_LINE LJ_MAX_MEM32 /* Max. source code line number. */ | |
| 65 #define LJ_MAX_XLEVEL 200 /* Max. syntactic nesting level. */ | |
| 66 #define LJ_MAX_BCINS (1<<26) /* Max. # of bytecode instructions. */ | |
| 67 #define LJ_MAX_SLOTS 250 /* Max. # of slots in a Lua func. */ | |
| 68 #define LJ_MAX_LOCVAR 200 /* Max. # of local variables. */ | |
| 69 #define LJ_MAX_UPVAL 60 /* Max. # of upvalues. */ | |
| 70 | |
| 71 #define LJ_MAX_IDXCHAIN 100 /* __index/__newindex chain limit. */ | |
| 72 #define LJ_STACK_EXTRA (5+2*LJ_FR2) /* Extra stack space (metamethods). */ | |
| 73 | |
| 74 #define LJ_NUM_CBPAGE 1 /* Number of FFI callback pages. */ | |
| 75 | |
| 76 /* Minimum table/buffer sizes. */ | |
| 77 #define LJ_MIN_GLOBAL 6 /* Min. global table size (hbits). */ | |
| 78 #define LJ_MIN_REGISTRY 2 /* Min. registry size (hbits). */ | |
| 79 #define LJ_MIN_STRTAB 256 /* Min. string table size (pow2). */ | |
| 80 #define LJ_MIN_SBUF 32 /* Min. string buffer length. */ | |
| 81 #define LJ_MIN_VECSZ 8 /* Min. size for growable vectors. */ | |
| 82 #define LJ_MIN_IRSZ 32 /* Min. size for growable IR. */ | |
| 83 | |
| 84 /* JIT compiler limits. */ | |
| 85 #define LJ_MAX_JSLOTS 250 /* Max. # of stack slots for a trace. */ | |
| 86 #define LJ_MAX_PHI 64 /* Max. # of PHIs for a loop. */ | |
| 87 #define LJ_MAX_EXITSTUBGR 16 /* Max. # of exit stub groups. */ | |
| 88 | |
| 89 /* Various macros. */ | |
| 90 #ifndef UNUSED | |
| 91 #define UNUSED(x) ((void)(x)) /* to avoid warnings */ | |
| 92 #endif | |
| 93 | |
| 94 #define U64x(hi, lo) (((uint64_t)0x##hi << 32) + (uint64_t)0x##lo) | |
| 95 #define i32ptr(p) ((int32_t)(intptr_t)(void *)(p)) | |
| 96 #define u32ptr(p) ((uint32_t)(intptr_t)(void *)(p)) | |
| 97 #define i64ptr(p) ((int64_t)(intptr_t)(void *)(p)) | |
| 98 #define u64ptr(p) ((uint64_t)(intptr_t)(void *)(p)) | |
| 99 #define igcptr(p) (LJ_GC64 ? i64ptr(p) : i32ptr(p)) | |
| 100 | |
| 101 #define checki8(x) ((x) == (int32_t)(int8_t)(x)) | |
| 102 #define checku8(x) ((x) == (int32_t)(uint8_t)(x)) | |
| 103 #define checki16(x) ((x) == (int32_t)(int16_t)(x)) | |
| 104 #define checku16(x) ((x) == (int32_t)(uint16_t)(x)) | |
| 105 #define checki32(x) ((x) == (int32_t)(x)) | |
| 106 #define checku32(x) ((x) == (uint32_t)(x)) | |
| 107 #define checkptr31(x) (((uint64_t)(uintptr_t)(x) >> 31) == 0) | |
| 108 #define checkptr32(x) ((uintptr_t)(x) == (uint32_t)(uintptr_t)(x)) | |
| 109 #define checkptr47(x) (((uint64_t)(uintptr_t)(x) >> 47) == 0) | |
| 110 #define checkptrGC(x) (LJ_GC64 ? checkptr47((x)) : LJ_64 ? checkptr31((x)) :1) | |
| 111 | |
| 112 /* Every half-decent C compiler transforms this into a rotate instruction. */ | |
| 113 #define lj_rol(x, n) (((x)<<(n)) | ((x)>>(-(int)(n)&(8*sizeof(x)-1)))) | |
| 114 #define lj_ror(x, n) (((x)<<(-(int)(n)&(8*sizeof(x)-1))) | ((x)>>(n))) | |
| 115 | |
| 116 /* A really naive Bloom filter. But sufficient for our needs. */ | |
| 117 typedef uintptr_t BloomFilter; | |
| 118 #define BLOOM_MASK (8*sizeof(BloomFilter) - 1) | |
| 119 #define bloombit(x) ((uintptr_t)1 << ((x) & BLOOM_MASK)) | |
| 120 #define bloomset(b, x) ((b) |= bloombit((x))) | |
| 121 #define bloomtest(b, x) ((b) & bloombit((x))) | |
| 122 | |
| 123 #if defined(__GNUC__) || defined(__clang__) || defined(__psp2__) | |
| 124 | |
| 125 #define LJ_NORET __attribute__((noreturn)) | |
| 126 #define LJ_ALIGN(n) __attribute__((aligned(n))) | |
| 127 #define LJ_INLINE inline | |
| 128 #define LJ_AINLINE inline __attribute__((always_inline)) | |
| 129 #define LJ_NOINLINE __attribute__((noinline)) | |
| 130 | |
| 131 #if defined(__ELF__) || defined(__MACH__) || defined(__psp2__) | |
| 132 #if !((defined(__sun__) && defined(__svr4__)) || defined(__CELLOS_LV2__)) | |
| 133 #define LJ_NOAPI extern __attribute__((visibility("hidden"))) | |
| 134 #endif | |
| 135 #endif | |
| 136 | |
| 137 /* Note: it's only beneficial to use fastcall on x86 and then only for up to | |
| 138 ** two non-FP args. The amalgamated compile covers all LJ_FUNC cases. Only | |
| 139 ** indirect calls and related tail-called C functions are marked as fastcall. | |
| 140 */ | |
| 141 #if defined(__i386__) | |
| 142 #define LJ_FASTCALL __attribute__((fastcall)) | |
| 143 #endif | |
| 144 | |
| 145 #define LJ_LIKELY(x) __builtin_expect(!!(x), 1) | |
| 146 #define LJ_UNLIKELY(x) __builtin_expect(!!(x), 0) | |
| 147 | |
| 148 #define lj_ffs(x) ((uint32_t)__builtin_ctz(x)) | |
| 149 /* Don't ask ... */ | |
| 150 #if defined(__INTEL_COMPILER) && (defined(__i386__) || defined(__x86_64__)) | |
| 151 static LJ_AINLINE uint32_t lj_fls(uint32_t x) | |
| 152 { | |
| 153 uint32_t r; __asm__("bsrl %1, %0" : "=r" (r) : "rm" (x) : "cc"); return r; | |
| 154 } | |
| 155 #else | |
| 156 #define lj_fls(x) ((uint32_t)(__builtin_clz(x)^31)) | |
| 157 #endif | |
| 158 | |
| 159 #if defined(__arm__) | |
| 160 static LJ_AINLINE uint32_t lj_bswap(uint32_t x) | |
| 161 { | |
| 162 #if defined(__psp2__) | |
| 163 return __builtin_rev(x); | |
| 164 #else | |
| 165 uint32_t r; | |
| 166 #if __ARM_ARCH_6__ || __ARM_ARCH_6J__ || __ARM_ARCH_6T2__ || __ARM_ARCH_6Z__ ||\ | |
| 167 __ARM_ARCH_6ZK__ || __ARM_ARCH_7__ || __ARM_ARCH_7A__ || __ARM_ARCH_7R__ | |
| 168 __asm__("rev %0, %1" : "=r" (r) : "r" (x)); | |
| 169 return r; | |
| 170 #else | |
| 171 #ifdef __thumb__ | |
| 172 r = x ^ lj_ror(x, 16); | |
| 173 #else | |
| 174 __asm__("eor %0, %1, %1, ror #16" : "=r" (r) : "r" (x)); | |
| 175 #endif | |
| 176 return ((r & 0xff00ffffu) >> 8) ^ lj_ror(x, 8); | |
| 177 #endif | |
| 178 #endif | |
| 179 } | |
| 180 | |
| 181 static LJ_AINLINE uint64_t lj_bswap64(uint64_t x) | |
| 182 { | |
| 183 return ((uint64_t)lj_bswap((uint32_t)x)<<32) | lj_bswap((uint32_t)(x>>32)); | |
| 184 } | |
| 185 #elif (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) || __clang__ | |
| 186 static LJ_AINLINE uint32_t lj_bswap(uint32_t x) | |
| 187 { | |
| 188 return (uint32_t)__builtin_bswap32((int32_t)x); | |
| 189 } | |
| 190 | |
| 191 static LJ_AINLINE uint64_t lj_bswap64(uint64_t x) | |
| 192 { | |
| 193 return (uint64_t)__builtin_bswap64((int64_t)x); | |
| 194 } | |
| 195 #elif defined(__i386__) || defined(__x86_64__) | |
| 196 static LJ_AINLINE uint32_t lj_bswap(uint32_t x) | |
| 197 { | |
| 198 uint32_t r; __asm__("bswap %0" : "=r" (r) : "0" (x)); return r; | |
| 199 } | |
| 200 | |
| 201 #if defined(__i386__) | |
| 202 static LJ_AINLINE uint64_t lj_bswap64(uint64_t x) | |
| 203 { | |
| 204 return ((uint64_t)lj_bswap((uint32_t)x)<<32) | lj_bswap((uint32_t)(x>>32)); | |
| 205 } | |
| 206 #else | |
| 207 static LJ_AINLINE uint64_t lj_bswap64(uint64_t x) | |
| 208 { | |
| 209 uint64_t r; __asm__("bswap %0" : "=r" (r) : "0" (x)); return r; | |
| 210 } | |
| 211 #endif | |
| 212 #else | |
| 213 static LJ_AINLINE uint32_t lj_bswap(uint32_t x) | |
| 214 { | |
| 215 return (x << 24) | ((x & 0xff00) << 8) | ((x >> 8) & 0xff00) | (x >> 24); | |
| 216 } | |
| 217 | |
| 218 static LJ_AINLINE uint64_t lj_bswap64(uint64_t x) | |
| 219 { | |
| 220 return (uint64_t)lj_bswap((uint32_t)(x >> 32)) | | |
| 221 ((uint64_t)lj_bswap((uint32_t)x) << 32); | |
| 222 } | |
| 223 #endif | |
| 224 | |
| 225 typedef union __attribute__((packed)) Unaligned16 { | |
| 226 uint16_t u; | |
| 227 uint8_t b[2]; | |
| 228 } Unaligned16; | |
| 229 | |
| 230 typedef union __attribute__((packed)) Unaligned32 { | |
| 231 uint32_t u; | |
| 232 uint8_t b[4]; | |
| 233 } Unaligned32; | |
| 234 | |
| 235 /* Unaligned load of uint16_t. */ | |
| 236 static LJ_AINLINE uint16_t lj_getu16(const void *p) | |
| 237 { | |
| 238 return ((const Unaligned16 *)p)->u; | |
| 239 } | |
| 240 | |
| 241 /* Unaligned load of uint32_t. */ | |
| 242 static LJ_AINLINE uint32_t lj_getu32(const void *p) | |
| 243 { | |
| 244 return ((const Unaligned32 *)p)->u; | |
| 245 } | |
| 246 | |
| 247 #elif defined(_MSC_VER) | |
| 248 | |
| 249 #define LJ_NORET __declspec(noreturn) | |
| 250 #define LJ_ALIGN(n) __declspec(align(n)) | |
| 251 #define LJ_INLINE __inline | |
| 252 #define LJ_AINLINE __forceinline | |
| 253 #define LJ_NOINLINE __declspec(noinline) | |
| 254 #if defined(_M_IX86) | |
| 255 #define LJ_FASTCALL __fastcall | |
| 256 #endif | |
| 257 | |
| 258 #ifdef _M_PPC | |
| 259 unsigned int _CountLeadingZeros(long); | |
| 260 #pragma intrinsic(_CountLeadingZeros) | |
| 261 static LJ_AINLINE uint32_t lj_fls(uint32_t x) | |
| 262 { | |
| 263 return _CountLeadingZeros(x) ^ 31; | |
| 264 } | |
| 265 #else | |
| 266 unsigned char _BitScanForward(unsigned long *, unsigned long); | |
| 267 unsigned char _BitScanReverse(unsigned long *, unsigned long); | |
| 268 #pragma intrinsic(_BitScanForward) | |
| 269 #pragma intrinsic(_BitScanReverse) | |
| 270 | |
| 271 static LJ_AINLINE uint32_t lj_ffs(uint32_t x) | |
| 272 { | |
| 273 unsigned long r; _BitScanForward(&r, x); return (uint32_t)r; | |
| 274 } | |
| 275 | |
| 276 static LJ_AINLINE uint32_t lj_fls(uint32_t x) | |
| 277 { | |
| 278 unsigned long r; _BitScanReverse(&r, x); return (uint32_t)r; | |
| 279 } | |
| 280 #endif | |
| 281 | |
| 282 unsigned long _byteswap_ulong(unsigned long); | |
| 283 uint64_t _byteswap_uint64(uint64_t); | |
| 284 #define lj_bswap(x) (_byteswap_ulong((x))) | |
| 285 #define lj_bswap64(x) (_byteswap_uint64((x))) | |
| 286 | |
| 287 #if defined(_M_PPC) && defined(LUAJIT_NO_UNALIGNED) | |
| 288 /* | |
| 289 ** Replacement for unaligned loads on Xbox 360. Disabled by default since it's | |
| 290 ** usually more costly than the occasional stall when crossing a cache-line. | |
| 291 */ | |
| 292 static LJ_AINLINE uint16_t lj_getu16(const void *v) | |
| 293 { | |
| 294 const uint8_t *p = (const uint8_t *)v; | |
| 295 return (uint16_t)((p[0]<<8) | p[1]); | |
| 296 } | |
| 297 static LJ_AINLINE uint32_t lj_getu32(const void *v) | |
| 298 { | |
| 299 const uint8_t *p = (const uint8_t *)v; | |
| 300 return (uint32_t)((p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3]); | |
| 301 } | |
| 302 #else | |
| 303 /* Unaligned loads are generally ok on x86/x64. */ | |
| 304 #define lj_getu16(p) (*(uint16_t *)(p)) | |
| 305 #define lj_getu32(p) (*(uint32_t *)(p)) | |
| 306 #endif | |
| 307 | |
| 308 #else | |
| 309 #error "missing defines for your compiler" | |
| 310 #endif | |
| 311 | |
| 312 /* Optional defines. */ | |
| 313 #ifndef LJ_FASTCALL | |
| 314 #define LJ_FASTCALL | |
| 315 #endif | |
| 316 #ifndef LJ_NORET | |
| 317 #define LJ_NORET | |
| 318 #endif | |
| 319 #ifndef LJ_NOAPI | |
| 320 #define LJ_NOAPI extern | |
| 321 #endif | |
| 322 #ifndef LJ_LIKELY | |
| 323 #define LJ_LIKELY(x) (x) | |
| 324 #define LJ_UNLIKELY(x) (x) | |
| 325 #endif | |
| 326 | |
| 327 /* Attributes for internal functions. */ | |
| 328 #define LJ_DATA LJ_NOAPI | |
| 329 #define LJ_DATADEF | |
| 330 #define LJ_ASMF LJ_NOAPI | |
| 331 #define LJ_FUNCA LJ_NOAPI | |
| 332 #if defined(ljamalg_c) | |
| 333 #define LJ_FUNC static | |
| 334 #else | |
| 335 #define LJ_FUNC LJ_NOAPI | |
| 336 #endif | |
| 337 #define LJ_FUNC_NORET LJ_FUNC LJ_NORET | |
| 338 #define LJ_FUNCA_NORET LJ_FUNCA LJ_NORET | |
| 339 #define LJ_ASMF_NORET LJ_ASMF LJ_NORET | |
| 340 | |
| 341 /* Internal assertions. */ | |
| 342 #if defined(LUA_USE_ASSERT) || defined(LUA_USE_APICHECK) | |
| 343 #define lj_assert_check(g, c, ...) \ | |
| 344 ((c) ? (void)0 : \ | |
| 345 (lj_assert_fail((g), __FILE__, __LINE__, __func__, __VA_ARGS__), 0)) | |
| 346 #define lj_checkapi(c, ...) lj_assert_check(G(L), (c), __VA_ARGS__) | |
| 347 #else | |
| 348 #define lj_checkapi(c, ...) ((void)L) | |
| 349 #endif | |
| 350 | |
| 351 #ifdef LUA_USE_ASSERT | |
| 352 #define lj_assertG_(g, c, ...) lj_assert_check((g), (c), __VA_ARGS__) | |
| 353 #define lj_assertG(c, ...) lj_assert_check(g, (c), __VA_ARGS__) | |
| 354 #define lj_assertL(c, ...) lj_assert_check(G(L), (c), __VA_ARGS__) | |
| 355 #define lj_assertX(c, ...) lj_assert_check(NULL, (c), __VA_ARGS__) | |
| 356 #define check_exp(c, e) (lj_assertX((c), #c), (e)) | |
| 357 #else | |
| 358 #define lj_assertG_(g, c, ...) ((void)0) | |
| 359 #define lj_assertG(c, ...) ((void)g) | |
| 360 #define lj_assertL(c, ...) ((void)L) | |
| 361 #define lj_assertX(c, ...) ((void)0) | |
| 362 #define check_exp(c, e) (e) | |
| 363 #endif | |
| 364 | |
| 365 /* Static assertions. */ | |
| 366 #define LJ_ASSERT_NAME2(name, line) name ## line | |
| 367 #define LJ_ASSERT_NAME(line) LJ_ASSERT_NAME2(lj_assert_, line) | |
| 368 #ifdef __COUNTER__ | |
| 369 #define LJ_STATIC_ASSERT(cond) \ | |
| 370 extern void LJ_ASSERT_NAME(__COUNTER__)(int STATIC_ASSERTION_FAILED[(cond)?1:-1]) | |
| 371 #else | |
| 372 #define LJ_STATIC_ASSERT(cond) \ | |
| 373 extern void LJ_ASSERT_NAME(__LINE__)(int STATIC_ASSERTION_FAILED[(cond)?1:-1]) | |
| 374 #endif | |
| 375 | |
| 376 /* PRNG state. Need this here, details in lj_prng.h. */ | |
| 377 typedef struct PRNGState { | |
| 378 uint64_t u[4]; | |
| 379 } PRNGState; | |
| 380 | |
| 381 #endif |