1/*
2** LuaJIT common internal definitions.
3** Copyright (C) 2005-2021 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. */
13typedef __int8 int8_t;
14typedef __int16 int16_t;
15typedef __int32 int32_t;
16typedef __int64 int64_t;
17typedef unsigned __int8 uint8_t;
18typedef unsigned __int16 uint16_t;
19typedef unsigned __int32 uint32_t;
20typedef unsigned __int64 uint64_t;
21#ifdef _WIN64
22typedef __int64 intptr_t;
23typedef unsigned __int64 uintptr_t;
24#else
25typedef __int32 intptr_t;
26typedef unsigned __int32 uintptr_t;
27#endif
28#elif defined(__symbian__)
29/* Cough. */
30typedef signed char int8_t;
31typedef short int int16_t;
32typedef int int32_t;
33typedef long long int64_t;
34typedef unsigned char uint8_t;
35typedef unsigned short int uint16_t;
36typedef unsigned int uint32_t;
37typedef unsigned long long uint64_t;
38typedef int intptr_t;
39typedef 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. */
117typedef 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__))
151static 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__)
160static 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
181static 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__
186static LJ_AINLINE uint32_t lj_bswap(uint32_t x)
187{
188 return (uint32_t)__builtin_bswap32((int32_t)x);
189}
190
191static 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__)
196static 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__)
202static 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
207static 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
213static LJ_AINLINE uint32_t lj_bswap(uint32_t x)
214{
215 return (x << 24) | ((x & 0xff00) << 8) | ((x >> 8) & 0xff00) | (x >> 24);
216}
217
218static 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
225typedef union __attribute__((packed)) Unaligned16 {
226 uint16_t u;
227 uint8_t b[2];
228} Unaligned16;
229
230typedef union __attribute__((packed)) Unaligned32 {
231 uint32_t u;
232 uint8_t b[4];
233} Unaligned32;
234
235/* Unaligned load of uint16_t. */
236static LJ_AINLINE uint16_t lj_getu16(const void *p)
237{
238 return ((const Unaligned16 *)p)->u;
239}
240
241/* Unaligned load of uint32_t. */
242static 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
259unsigned int _CountLeadingZeros(long);
260#pragma intrinsic(_CountLeadingZeros)
261static LJ_AINLINE uint32_t lj_fls(uint32_t x)
262{
263 return _CountLeadingZeros(x) ^ 31;
264}
265#else
266unsigned char _BitScanForward(unsigned long *, unsigned long);
267unsigned char _BitScanReverse(unsigned long *, unsigned long);
268#pragma intrinsic(_BitScanForward)
269#pragma intrinsic(_BitScanReverse)
270
271static LJ_AINLINE uint32_t lj_ffs(uint32_t x)
272{
273 unsigned long r; _BitScanForward(&r, x); return (uint32_t)r;
274}
275
276static 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
282unsigned long _byteswap_ulong(unsigned long);
283uint64_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*/
292static 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}
297static 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. */
377typedef struct PRNGState {
378 uint64_t u[4];
379} PRNGState;
380
381#endif
382