1/*
2** LuaJIT common internal definitions.
3** Copyright (C) 2005-2014 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)
12/* 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_MEM 0x7fffff00 /* Max. total memory allocation. */
50#define LJ_MAX_ALLOC LJ_MAX_MEM /* Max. individual allocation length. */
51#define LJ_MAX_STR LJ_MAX_MEM /* Max. string length. */
52#define LJ_MAX_UDATA LJ_MAX_MEM /* Max. userdata length. */
53
54#define LJ_MAX_STRTAB (1<<26) /* Max. string table size. */
55#define LJ_MAX_HBITS 26 /* Max. hash bits. */
56#define LJ_MAX_ABITS 28 /* Max. bits of array key. */
57#define LJ_MAX_ASIZE ((1<<(LJ_MAX_ABITS-1))+1) /* Max. array part size. */
58#define LJ_MAX_COLOSIZE 16 /* Max. elems for colocated array. */
59
60#define LJ_MAX_LINE LJ_MAX_MEM /* Max. source code line number. */
61#define LJ_MAX_XLEVEL 200 /* Max. syntactic nesting level. */
62#define LJ_MAX_BCINS (1<<26) /* Max. # of bytecode instructions. */
63#define LJ_MAX_SLOTS 250 /* Max. # of slots in a Lua func. */
64#define LJ_MAX_LOCVAR 200 /* Max. # of local variables. */
65#define LJ_MAX_UPVAL 60 /* Max. # of upvalues. */
66
67#define LJ_MAX_IDXCHAIN 100 /* __index/__newindex chain limit. */
68#define LJ_STACK_EXTRA 5 /* Extra stack space (metamethods). */
69
70#define LJ_NUM_CBPAGE 1 /* Number of FFI callback pages. */
71
72/* Minimum table/buffer sizes. */
73#define LJ_MIN_GLOBAL 6 /* Min. global table size (hbits). */
74#define LJ_MIN_REGISTRY 2 /* Min. registry size (hbits). */
75#define LJ_MIN_STRTAB 256 /* Min. string table size (pow2). */
76#define LJ_MIN_SBUF 32 /* Min. string buffer length. */
77#define LJ_MIN_VECSZ 8 /* Min. size for growable vectors. */
78#define LJ_MIN_IRSZ 32 /* Min. size for growable IR. */
79#define LJ_MIN_K64SZ 16 /* Min. size for chained K64Array. */
80
81/* JIT compiler limits. */
82#define LJ_MAX_JSLOTS 250 /* Max. # of stack slots for a trace. */
83#define LJ_MAX_PHI 64 /* Max. # of PHIs for a loop. */
84#define LJ_MAX_EXITSTUBGR 16 /* Max. # of exit stub groups. */
85
86/* Various macros. */
87#ifndef UNUSED
88#define UNUSED(x) ((void)(x)) /* to avoid warnings */
89#endif
90
91#define U64x(hi, lo) (((uint64_t)0x##hi << 32) + (uint64_t)0x##lo)
92#define i32ptr(p) ((int32_t)(intptr_t)(void *)(p))
93#define u32ptr(p) ((uint32_t)(intptr_t)(void *)(p))
94
95#define checki8(x) ((x) == (int32_t)(int8_t)(x))
96#define checku8(x) ((x) == (int32_t)(uint8_t)(x))
97#define checki16(x) ((x) == (int32_t)(int16_t)(x))
98#define checku16(x) ((x) == (int32_t)(uint16_t)(x))
99#define checki32(x) ((x) == (int32_t)(x))
100#define checku32(x) ((x) == (uint32_t)(x))
101#define checkptr32(x) ((uintptr_t)(x) == (uint32_t)(uintptr_t)(x))
102
103/* Every half-decent C compiler transforms this into a rotate instruction. */
104#define lj_rol(x, n) (((x)<<(n)) | ((x)>>(-(int)(n)&(8*sizeof(x)-1))))
105#define lj_ror(x, n) (((x)<<(-(int)(n)&(8*sizeof(x)-1))) | ((x)>>(n)))
106
107/* A really naive Bloom filter. But sufficient for our needs. */
108typedef uintptr_t BloomFilter;
109#define BLOOM_MASK (8*sizeof(BloomFilter) - 1)
110#define bloombit(x) ((uintptr_t)1 << ((x) & BLOOM_MASK))
111#define bloomset(b, x) ((b) |= bloombit((x)))
112#define bloomtest(b, x) ((b) & bloombit((x)))
113
114#if defined(__GNUC__)
115
116#define LJ_NORET __attribute__((noreturn))
117#define LJ_ALIGN(n) __attribute__((aligned(n)))
118#define LJ_INLINE inline
119#define LJ_AINLINE inline __attribute__((always_inline))
120#define LJ_NOINLINE __attribute__((noinline))
121
122#if defined(__ELF__) || defined(__MACH__)
123#if !((defined(__sun__) && defined(__svr4__)) || defined(__CELLOS_LV2__))
124#define LJ_NOAPI extern __attribute__((visibility("hidden")))
125#endif
126#endif
127
128/* Note: it's only beneficial to use fastcall on x86 and then only for up to
129** two non-FP args. The amalgamated compile covers all LJ_FUNC cases. Only
130** indirect calls and related tail-called C functions are marked as fastcall.
131*/
132#if defined(__i386__)
133#define LJ_FASTCALL __attribute__((fastcall))
134#endif
135
136#define LJ_LIKELY(x) __builtin_expect(!!(x), 1)
137#define LJ_UNLIKELY(x) __builtin_expect(!!(x), 0)
138
139#define lj_ffs(x) ((uint32_t)__builtin_ctz(x))
140/* Don't ask ... */
141#if defined(__INTEL_COMPILER) && (defined(__i386__) || defined(__x86_64__))
142static LJ_AINLINE uint32_t lj_fls(uint32_t x)
143{
144 uint32_t r; __asm__("bsrl %1, %0" : "=r" (r) : "rm" (x) : "cc"); return r;
145}
146#else
147#define lj_fls(x) ((uint32_t)(__builtin_clz(x)^31))
148#endif
149
150#if defined(__arm__)
151static LJ_AINLINE uint32_t lj_bswap(uint32_t x)
152{
153 uint32_t r;
154#if __ARM_ARCH_6__ || __ARM_ARCH_6J__ || __ARM_ARCH_6T2__ || __ARM_ARCH_6Z__ ||\
155 __ARM_ARCH_6ZK__ || __ARM_ARCH_7__ || __ARM_ARCH_7A__ || __ARM_ARCH_7R__
156 __asm__("rev %0, %1" : "=r" (r) : "r" (x));
157 return r;
158#else
159#ifdef __thumb__
160 r = x ^ lj_ror(x, 16);
161#else
162 __asm__("eor %0, %1, %1, ror #16" : "=r" (r) : "r" (x));
163#endif
164 return ((r & 0xff00ffffu) >> 8) ^ lj_ror(x, 8);
165#endif
166}
167
168static LJ_AINLINE uint64_t lj_bswap64(uint64_t x)
169{
170 return ((uint64_t)lj_bswap((uint32_t)x)<<32) | lj_bswap((uint32_t)(x>>32));
171}
172#elif (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
173static LJ_AINLINE uint32_t lj_bswap(uint32_t x)
174{
175 return (uint32_t)__builtin_bswap32((int32_t)x);
176}
177
178static LJ_AINLINE uint64_t lj_bswap64(uint64_t x)
179{
180 return (uint64_t)__builtin_bswap64((int64_t)x);
181}
182#elif defined(__i386__) || defined(__x86_64__)
183static LJ_AINLINE uint32_t lj_bswap(uint32_t x)
184{
185 uint32_t r; __asm__("bswap %0" : "=r" (r) : "0" (x)); return r;
186}
187
188#if defined(__i386__)
189static LJ_AINLINE uint64_t lj_bswap64(uint64_t x)
190{
191 return ((uint64_t)lj_bswap((uint32_t)x)<<32) | lj_bswap((uint32_t)(x>>32));
192}
193#else
194static LJ_AINLINE uint64_t lj_bswap64(uint64_t x)
195{
196 uint64_t r; __asm__("bswap %0" : "=r" (r) : "0" (x)); return r;
197}
198#endif
199#else
200static LJ_AINLINE uint32_t lj_bswap(uint32_t x)
201{
202 return (x << 24) | ((x & 0xff00) << 8) | ((x >> 8) & 0xff00) | (x >> 24);
203}
204
205static LJ_AINLINE uint64_t lj_bswap64(uint64_t x)
206{
207 return (uint64_t)lj_bswap((uint32_t)(x >> 32)) |
208 ((uint64_t)lj_bswap((uint32_t)x) << 32);
209}
210#endif
211
212typedef union __attribute__((packed)) Unaligned16 {
213 uint16_t u;
214 uint8_t b[2];
215} Unaligned16;
216
217typedef union __attribute__((packed)) Unaligned32 {
218 uint32_t u;
219 uint8_t b[4];
220} Unaligned32;
221
222/* Unaligned load of uint16_t. */
223static LJ_AINLINE uint16_t lj_getu16(const void *p)
224{
225 return ((const Unaligned16 *)p)->u;
226}
227
228/* Unaligned load of uint32_t. */
229static LJ_AINLINE uint32_t lj_getu32(const void *p)
230{
231 return ((const Unaligned32 *)p)->u;
232}
233
234#elif defined(_MSC_VER)
235
236#define LJ_NORET __declspec(noreturn)
237#define LJ_ALIGN(n) __declspec(align(n))
238#define LJ_INLINE __inline
239#define LJ_AINLINE __forceinline
240#define LJ_NOINLINE __declspec(noinline)
241#if defined(_M_IX86)
242#define LJ_FASTCALL __fastcall
243#endif
244
245#ifdef _M_PPC
246unsigned int _CountLeadingZeros(long);
247#pragma intrinsic(_CountLeadingZeros)
248static LJ_AINLINE uint32_t lj_fls(uint32_t x)
249{
250 return _CountLeadingZeros(x) ^ 31;
251}
252#else
253unsigned char _BitScanForward(uint32_t *, unsigned long);
254unsigned char _BitScanReverse(uint32_t *, unsigned long);
255#pragma intrinsic(_BitScanForward)
256#pragma intrinsic(_BitScanReverse)
257
258static LJ_AINLINE uint32_t lj_ffs(uint32_t x)
259{
260 uint32_t r; _BitScanForward(&r, x); return r;
261}
262
263static LJ_AINLINE uint32_t lj_fls(uint32_t x)
264{
265 uint32_t r; _BitScanReverse(&r, x); return r;
266}
267#endif
268
269unsigned long _byteswap_ulong(unsigned long);
270uint64_t _byteswap_uint64(uint64_t);
271#define lj_bswap(x) (_byteswap_ulong((x)))
272#define lj_bswap64(x) (_byteswap_uint64((x)))
273
274#if defined(_M_PPC) && defined(LUAJIT_NO_UNALIGNED)
275/*
276** Replacement for unaligned loads on Xbox 360. Disabled by default since it's
277** usually more costly than the occasional stall when crossing a cache-line.
278*/
279static LJ_AINLINE uint16_t lj_getu16(const void *v)
280{
281 const uint8_t *p = (const uint8_t *)v;
282 return (uint16_t)((p[0]<<8) | p[1]);
283}
284static LJ_AINLINE uint32_t lj_getu32(const void *v)
285{
286 const uint8_t *p = (const uint8_t *)v;
287 return (uint32_t)((p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3]);
288}
289#else
290/* Unaligned loads are generally ok on x86/x64. */
291#define lj_getu16(p) (*(uint16_t *)(p))
292#define lj_getu32(p) (*(uint32_t *)(p))
293#endif
294
295#else
296#error "missing defines for your compiler"
297#endif
298
299/* Optional defines. */
300#ifndef LJ_FASTCALL
301#define LJ_FASTCALL
302#endif
303#ifndef LJ_NORET
304#define LJ_NORET
305#endif
306#ifndef LJ_NOAPI
307#define LJ_NOAPI extern
308#endif
309#ifndef LJ_LIKELY
310#define LJ_LIKELY(x) (x)
311#define LJ_UNLIKELY(x) (x)
312#endif
313
314/* Attributes for internal functions. */
315#define LJ_DATA LJ_NOAPI
316#define LJ_DATADEF
317#define LJ_ASMF LJ_NOAPI
318#define LJ_FUNCA LJ_NOAPI
319#if defined(ljamalg_c)
320#define LJ_FUNC static
321#else
322#define LJ_FUNC LJ_NOAPI
323#endif
324#define LJ_FUNC_NORET LJ_FUNC LJ_NORET
325#define LJ_FUNCA_NORET LJ_FUNCA LJ_NORET
326#define LJ_ASMF_NORET LJ_ASMF LJ_NORET
327
328/* Runtime assertions. */
329#ifdef lua_assert
330#define check_exp(c, e) (lua_assert(c), (e))
331#define api_check(l, e) lua_assert(e)
332#else
333#define lua_assert(c) ((void)0)
334#define check_exp(c, e) (e)
335#define api_check luai_apicheck
336#endif
337
338/* Static assertions. */
339#define LJ_ASSERT_NAME2(name, line) name ## line
340#define LJ_ASSERT_NAME(line) LJ_ASSERT_NAME2(lj_assert_, line)
341#ifdef __COUNTER__
342#define LJ_STATIC_ASSERT(cond) \
343 extern void LJ_ASSERT_NAME(__COUNTER__)(int STATIC_ASSERTION_FAILED[(cond)?1:-1])
344#else
345#define LJ_STATIC_ASSERT(cond) \
346 extern void LJ_ASSERT_NAME(__LINE__)(int STATIC_ASSERTION_FAILED[(cond)?1:-1])
347#endif
348
349#endif
350