Branch data Line data Source code
1 : : // This file is a part of Julia. License is MIT: https://julialang.org/license
2 : :
3 : : #ifndef JL_DTYPES_H
4 : : #define JL_DTYPES_H
5 : :
6 : : #include <stddef.h>
7 : : #include <stddef.h> // double include of stddef.h fixes #3421
8 : : #include <stdint.h>
9 : : #include <string.h> // memcpy
10 : : #include <errno.h>
11 : : #include <stdlib.h>
12 : : #include <stdio.h>
13 : : #include <math.h> // NAN and INF constants
14 : :
15 : : #include "platform.h"
16 : : #include "analyzer_annotations.h"
17 : :
18 : : #if !defined(_OS_WINDOWS_)
19 : : #include <inttypes.h>
20 : : #endif
21 : :
22 : : #if defined(_OS_WINDOWS_)
23 : :
24 : : #include <stdio.h>
25 : : #include <stdlib.h>
26 : : #include <sys/stat.h>
27 : : #define WIN32_LEAN_AND_MEAN
28 : : #include <windows.h>
29 : :
30 : : #if defined(_COMPILER_MICROSOFT_) && !defined(_SSIZE_T_) && !defined(_SSIZE_T_DEFINED)
31 : :
32 : : /* See https://github.com/JuliaLang/julia/pull/44587 */
33 : : typedef intptr_t ssize_t;
34 : : #define SSIZE_MAX INTPTR_MAX
35 : : #define _SSIZE_T_
36 : : #define _SSIZE_T_DEFINED
37 : :
38 : : #endif /* defined(_COMPILER_MICROSOFT_) && !defined(_SSIZE_T_) && !defined(_SSIZE_T_DEFINED) */
39 : :
40 : : #if !defined(_COMPILER_GCC_)
41 : :
42 : : #define strtoull _strtoui64
43 : : #define strtoll _strtoi64
44 : : #define strcasecmp _stricmp
45 : : #define strncasecmp _strnicmp
46 : : #define snprintf _snprintf
47 : : #define stat _stat
48 : :
49 : : #define STDIN_FILENO 0
50 : : #define STDOUT_FILENO 1
51 : : #define STDERR_FILENO 2
52 : :
53 : : #endif /* !_COMPILER_GCC_ */
54 : :
55 : : #endif /* _OS_WINDOWS_ */
56 : :
57 : :
58 : : /*
59 : : This file defines sane integer types for our target platforms. This
60 : : library only runs on machines with the following characteristics:
61 : :
62 : : - supports integer word sizes of 8, 16, 32, and 64 bits
63 : : - uses unsigned and signed 2's complement representations
64 : : - all pointer types are the same size
65 : : - there is an integer type with the same size as a pointer
66 : :
67 : : Some features require:
68 : : - IEEE 754 single- and double-precision floating point
69 : :
70 : : We assume the LP64 convention for 64-bit platforms.
71 : : */
72 : :
73 : : #ifdef _OS_WINDOWS_
74 : : #define STDCALL __stdcall
75 : : # ifdef LIBRARY_EXPORTS
76 : : # define JL_DLLEXPORT __declspec(dllexport)
77 : : # else
78 : : # define JL_DLLEXPORT __declspec(dllimport)
79 : : # endif
80 : : #define JL_DLLIMPORT __declspec(dllimport)
81 : : #else
82 : : #define STDCALL
83 : : # define JL_DLLEXPORT __attribute__ ((visibility("default")))
84 : : #define JL_DLLIMPORT
85 : : #endif
86 : :
87 : : #ifdef _OS_LINUX_
88 : : #include <endian.h>
89 : : #define LITTLE_ENDIAN __LITTLE_ENDIAN
90 : : #define BIG_ENDIAN __BIG_ENDIAN
91 : : #define PDP_ENDIAN __PDP_ENDIAN
92 : : #define BYTE_ORDER __BYTE_ORDER
93 : : #endif
94 : :
95 : : #if defined(__APPLE__) || defined(__FreeBSD__)
96 : : #include <machine/endian.h>
97 : : #define __LITTLE_ENDIAN LITTLE_ENDIAN
98 : : #define __BIG_ENDIAN BIG_ENDIAN
99 : : #define __PDP_ENDIAN PDP_ENDIAN
100 : : #define __BYTE_ORDER BYTE_ORDER
101 : : #endif
102 : :
103 : : #ifdef _OS_WINDOWS_
104 : : #define __LITTLE_ENDIAN 1234
105 : : #define __BIG_ENDIAN 4321
106 : : #define __PDP_ENDIAN 3412
107 : : #define __BYTE_ORDER __LITTLE_ENDIAN
108 : : #define __FLOAT_WORD_ORDER __LITTLE_ENDIAN
109 : : #define LITTLE_ENDIAN __LITTLE_ENDIAN
110 : : #define BIG_ENDIAN __BIG_ENDIAN
111 : : #define PDP_ENDIAN __PDP_ENDIAN
112 : : #define BYTE_ORDER __BYTE_ORDER
113 : : #endif
114 : :
115 : : #define LLT_ALLOC(n) malloc(n)
116 : : #define LLT_REALLOC(p,n) realloc((p),(n))
117 : : #define LLT_FREE(x) free(x)
118 : :
119 : : #define STATIC_INLINE static inline
120 : :
121 : : #if defined(_OS_WINDOWS_) && !defined(_COMPILER_GCC_)
122 : : # define NOINLINE __declspec(noinline)
123 : : # define NOINLINE_DECL(f) __declspec(noinline) f
124 : : #else
125 : : # define NOINLINE __attribute__((noinline))
126 : : # define NOINLINE_DECL(f) f __attribute__((noinline))
127 : : #endif
128 : :
129 : : #ifdef _COMPILER_MICROSOFT_
130 : : # ifdef _P64
131 : : # define JL_ATTRIBUTE_ALIGN_PTRSIZE(x) __declspec(align(8)) x
132 : : # else
133 : : # define JL_ATTRIBUTE_ALIGN_PTRSIZE(x) __declspec(align(4)) x
134 : : # endif
135 : : #elif defined(__GNUC__)
136 : : # define JL_ATTRIBUTE_ALIGN_PTRSIZE(x) x __attribute__ ((aligned (sizeof(void*))))
137 : : #else
138 : : # define JL_ATTRIBUTE_ALIGN_PTRSIZE(x)
139 : : #endif
140 : :
141 : : #ifdef __has_builtin
142 : : # define jl_has_builtin(x) __has_builtin(x)
143 : : #else
144 : : # define jl_has_builtin(x) 0
145 : : #endif
146 : :
147 : : #if jl_has_builtin(__builtin_assume)
148 : : #define jl_assume(cond) (__extension__ ({ \
149 : : __typeof__(cond) cond_ = (cond); \
150 : : __builtin_assume(!!(cond_)); \
151 : : cond_; \
152 : : }))
153 : : #elif defined(__GNUC__)
154 : 6809002708 : static inline void jl_assume_(int cond)
155 : : {
156 [ - + ]: 6809002708 : if (!cond) {
157 : 0 : __builtin_unreachable();
158 : : }
159 : 6809002708 : }
160 : : #define jl_assume(cond) (__extension__ ({ \
161 : : __typeof__(cond) cond_ = (cond); \
162 : : jl_assume_(!!(cond_)); \
163 : : cond_; \
164 : : }))
165 : : #else
166 : : #define jl_assume(cond) (cond)
167 : : #endif
168 : :
169 : : #if jl_has_builtin(__builtin_assume_aligned) || defined(_COMPILER_GCC_)
170 : : #define jl_assume_aligned(ptr, align) __builtin_assume_aligned(ptr, align)
171 : : #elif defined(__GNUC__)
172 : : #define jl_assume_aligned(ptr, align) (__extension__ ({ \
173 : : __typeof__(ptr) ptr_ = (ptr); \
174 : : jl_assume(((uintptr_t)ptr) % (align) == 0); \
175 : : ptr_; \
176 : : }))
177 : : #elif defined(__cplusplus)
178 : : template<typename T>
179 : : static inline T
180 : : jl_assume_aligned(T ptr, unsigned align)
181 : : {
182 : : (void)jl_assume(((uintptr_t)ptr) % align == 0);
183 : : return ptr;
184 : : }
185 : : #else
186 : : #define jl_assume_aligned(ptr, align) (ptr)
187 : : #endif
188 : :
189 : : typedef int bool_t;
190 : : typedef unsigned char byte_t; /* 1 byte */
191 : :
192 : : #ifdef _P64
193 : : #define TOP_BIT 0x8000000000000000
194 : : #define NBITS 64
195 : : typedef uint64_t uint_t; // preferred int type on platform
196 : : typedef int64_t int_t;
197 : : #else
198 : : #define TOP_BIT 0x80000000
199 : : #define NBITS 32
200 : : typedef uint32_t uint_t;
201 : : typedef int32_t int_t;
202 : : #endif
203 : :
204 : 36312951 : STATIC_INLINE unsigned int next_power_of_two(unsigned int val) JL_NOTSAFEPOINT
205 : : {
206 : : /* this function taken from libuv src/unix/core.c */
207 : 36312951 : val -= 1;
208 : 36312951 : val |= val >> 1;
209 : 36312951 : val |= val >> 2;
210 : 36312951 : val |= val >> 4;
211 : 36312951 : val |= val >> 8;
212 : 36312951 : val |= val >> 16;
213 : 36312951 : val += 1;
214 : 36312951 : return val;
215 : : }
216 : :
217 : : #define LLT_ALIGN(x, sz) (((x) + (sz)-1) & ~((sz)-1))
218 : :
219 : : // branch prediction annotations
220 : : #ifdef __GNUC__
221 : : #define __unlikely(x) __builtin_expect(!!(x), 0)
222 : : #define __likely(x) __builtin_expect(!!(x), 1)
223 : : #define JL_EXTENSION __extension__
224 : : #else
225 : : #define __unlikely(x) (x)
226 : : #define __likely(x) (x)
227 : : #define JL_EXTENSION
228 : : #endif
229 : :
230 : : #define DBL_MAXINT 9007199254740992LL
231 : : #define FLT_MAXINT 16777216
232 : : #define U64_MAX 18446744073709551615ULL
233 : : #define S64_MAX 9223372036854775807LL
234 : : #define S64_MIN (-S64_MAX - 1LL)
235 : : #define BIT63 0x8000000000000000LL
236 : : #define U32_MAX 4294967295L
237 : : #define S32_MAX 2147483647L
238 : : #define S32_MIN (-S32_MAX - 1L)
239 : : #define BIT31 0x80000000
240 : :
241 : : #define D_PNAN ((double)+NAN)
242 : : #define D_NNAN ((double)-NAN)
243 : : #define D_PINF ((double)+INFINITY)
244 : : #define D_NINF ((double)-INFINITY)
245 : : #define F_PNAN ((float)+NAN)
246 : : #define F_NNAN ((float)-NAN)
247 : : #define F_PINF ((float)+INFINITY)
248 : : #define F_NINF ((float)-INFINITY)
249 : :
250 : : typedef enum { T_INT8, T_UINT8, T_INT16, T_UINT16, T_INT32, T_UINT32,
251 : : T_INT64, T_UINT64, T_FLOAT, T_DOUBLE } numerictype_t;
252 : :
253 : : #define N_NUMTYPES ((int)T_DOUBLE+1)
254 : :
255 : : #ifdef _P64
256 : : # define T_PTRDIFF T_INT64
257 : : # define T_SIZE T_UINT64
258 : : #else
259 : : # define T_PTRDIFF T_INT32
260 : : # define T_SIZE T_UINT32
261 : : #endif
262 : :
263 : : #if defined(__GNUC__) && __GNUC__ >= 7
264 : : #define JL_FALLTHROUGH __attribute__((fallthrough))
265 : : #elif defined(__cplusplus) && defined(__clang_major__) && \
266 : : defined(__clang_minor__) && (__clang_major__ > 4 || __clang_minor__ >= 5)
267 : : // We require at least clang 3.x
268 : : #define JL_FALLTHROUGH [[clang::fallthrough]]
269 : : #else
270 : : #define JL_FALLTHROUGH
271 : : #endif
272 : :
273 : : #if defined(__GNUC__)
274 : : #define JL_UNUSED __attribute__((__unused__))
275 : : #else
276 : : #define JL_UNUSED
277 : : #endif
278 : :
279 : : STATIC_INLINE double jl_load_unaligned_f64(const void *ptr) JL_NOTSAFEPOINT
280 : : {
281 : : double val;
282 : : memcpy(&val, ptr, sizeof(double));
283 : : return val;
284 : : }
285 : :
286 : 133012000 : STATIC_INLINE uint64_t jl_load_unaligned_i64(const void *ptr) JL_NOTSAFEPOINT
287 : : {
288 : : uint64_t val;
289 : 133012000 : memcpy(&val, ptr, sizeof(uint64_t));
290 : 133012000 : return val;
291 : : }
292 : :
293 : : STATIC_INLINE double jl_load_ptraligned_f64(const void *ptr) JL_NOTSAFEPOINT
294 : : {
295 : : double val;
296 : : memcpy(&val, jl_assume_aligned(ptr, sizeof(void*)), sizeof(double));
297 : : return val;
298 : : }
299 : :
300 : : STATIC_INLINE uint64_t jl_load_ptraligned_i64(const void *ptr) JL_NOTSAFEPOINT
301 : : {
302 : : uint64_t val;
303 : : memcpy(&val, jl_assume_aligned(ptr, sizeof(void*)), sizeof(uint64_t));
304 : : return val;
305 : : }
306 : :
307 : :
308 : 3869586828 : STATIC_INLINE uint32_t jl_load_unaligned_i32(const void *ptr) JL_NOTSAFEPOINT
309 : : {
310 : : uint32_t val;
311 : 3869586828 : memcpy(&val, ptr, 4);
312 : 3869586828 : return val;
313 : : }
314 : 1085 : STATIC_INLINE uint16_t jl_load_unaligned_i16(const void *ptr) JL_NOTSAFEPOINT
315 : : {
316 : : uint16_t val;
317 : 1085 : memcpy(&val, ptr, 2);
318 : 1085 : return val;
319 : : }
320 : :
321 : : STATIC_INLINE void jl_store_unaligned_i64(void *ptr, uint64_t val) JL_NOTSAFEPOINT
322 : : {
323 : : memcpy(ptr, &val, 8);
324 : : }
325 : : STATIC_INLINE void jl_store_unaligned_i32(void *ptr, uint32_t val) JL_NOTSAFEPOINT
326 : : {
327 : : memcpy(ptr, &val, 4);
328 : : }
329 : : STATIC_INLINE void jl_store_unaligned_i16(void *ptr, uint16_t val) JL_NOTSAFEPOINT
330 : : {
331 : : memcpy(ptr, &val, 2);
332 : : }
333 : :
334 : 52837593 : STATIC_INLINE void *malloc_s(size_t sz) JL_NOTSAFEPOINT {
335 : 52837593 : int last_errno = errno;
336 : : #ifdef _OS_WINDOWS_
337 : : DWORD last_error = GetLastError();
338 : : #endif
339 [ + + ]: 52837593 : void *p = malloc(sz == 0 ? 1 : sz);
340 [ - + ]: 52837593 : if (p == NULL) {
341 : 0 : perror("(julia) malloc");
342 : 0 : abort();
343 : : }
344 : : #ifdef _OS_WINDOWS_
345 : : SetLastError(last_error);
346 : : #endif
347 : 52837593 : errno = last_errno;
348 : 52837593 : return p;
349 : : }
350 : :
351 : 470616 : STATIC_INLINE void *realloc_s(void *p, size_t sz) JL_NOTSAFEPOINT {
352 : 470616 : int last_errno = errno;
353 : : #ifdef _OS_WINDOWS_
354 : : DWORD last_error = GetLastError();
355 : : #endif
356 [ + - ]: 470616 : p = realloc(p, sz == 0 ? 1 : sz);
357 [ - + ]: 470616 : if (p == NULL) {
358 : 0 : perror("(julia) realloc");
359 : 0 : abort();
360 : : }
361 : : #ifdef _OS_WINDOWS_
362 : : SetLastError(last_error);
363 : : #endif
364 : 470616 : errno = last_errno;
365 : 470616 : return p;
366 : : }
367 : :
368 : : #endif /* DTYPES_H */
|