v8config.h 15.2 KB
Newer Older
1
// Copyright 2013 the V8 project authors. All rights reserved.
2 3
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
4 5 6 7

#ifndef V8CONFIG_H_
#define V8CONFIG_H_

8 9
// clang-format off

10 11 12 13
// Platform headers for feature detection below.
#if defined(__ANDROID__)
# include <sys/cdefs.h>
#elif defined(__APPLE__)
14
# include <TargetConditionals.h>
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
#elif defined(__linux__)
# include <features.h>
#endif


// This macro allows to test for the version of the GNU C library (or
// a compatible C library that masquerades as glibc). It evaluates to
// 0 if libc is not GNU libc or compatible.
// Use like:
//  #if V8_GLIBC_PREREQ(2, 3)
//   ...
//  #endif
#if defined(__GLIBC__) && defined(__GLIBC_MINOR__)
# define V8_GLIBC_PREREQ(major, minor)                                    \
    ((__GLIBC__ * 100 + __GLIBC_MINOR__) >= ((major) * 100 + (minor)))
#else
# define V8_GLIBC_PREREQ(major, minor) 0
#endif


// This macro allows to test for the version of the GNU C++ compiler.
// Note that this also applies to compilers that masquerade as GCC,
// for example clang and the Intel C++ compiler for Linux.
// Use like:
//  #if V8_GNUC_PREREQ(4, 3, 1)
//   ...
//  #endif
#if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__)
# define V8_GNUC_PREREQ(major, minor, patchlevel)                         \
    ((__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) >=   \
     ((major) * 10000 + (minor) * 100 + (patchlevel)))
#elif defined(__GNUC__) && defined(__GNUC_MINOR__)
47 48
# define V8_GNUC_PREREQ(major, minor, patchlevel)      \
    ((__GNUC__ * 10000 + __GNUC_MINOR__ * 100) >=      \
49 50 51 52 53 54 55
     ((major) * 10000 + (minor) * 100 + (patchlevel)))
#else
# define V8_GNUC_PREREQ(major, minor, patchlevel) 0
#endif



56 57 58 59 60 61 62 63 64 65 66 67 68 69
// -----------------------------------------------------------------------------
// Operating system detection
//
//  V8_OS_ANDROID       - Android
//  V8_OS_BSD           - BSDish (Mac OS X, Net/Free/Open/DragonFlyBSD)
//  V8_OS_CYGWIN        - Cygwin
//  V8_OS_DRAGONFLYBSD  - DragonFlyBSD
//  V8_OS_FREEBSD       - FreeBSD
//  V8_OS_LINUX         - Linux
//  V8_OS_MACOSX        - Mac OS X
//  V8_OS_NACL          - Native Client
//  V8_OS_NETBSD        - NetBSD
//  V8_OS_OPENBSD       - OpenBSD
//  V8_OS_POSIX         - POSIX compatible (mostly everything except Windows)
70
//  V8_OS_QNX           - QNX Neutrino
71
//  V8_OS_SOLARIS       - Sun Solaris and OpenSolaris
72
//  V8_OS_AIX           - AIX
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
//  V8_OS_WIN           - Microsoft Windows

#if defined(__ANDROID__)
# define V8_OS_ANDROID 1
# define V8_OS_LINUX 1
# define V8_OS_POSIX 1
#elif defined(__APPLE__)
# define V8_OS_BSD 1
# define V8_OS_MACOSX 1
# define V8_OS_POSIX 1
#elif defined(__native_client__)
# define V8_OS_NACL 1
# define V8_OS_POSIX 1
#elif defined(__CYGWIN__)
# define V8_OS_CYGWIN 1
# define V8_OS_POSIX 1
#elif defined(__linux__)
# define V8_OS_LINUX 1
# define V8_OS_POSIX 1
#elif defined(__sun)
# define V8_OS_POSIX 1
# define V8_OS_SOLARIS 1
95 96 97
#elif defined(_AIX)
#define V8_OS_POSIX 1
#define V8_OS_AIX 1
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
#elif defined(__FreeBSD__)
# define V8_OS_BSD 1
# define V8_OS_FREEBSD 1
# define V8_OS_POSIX 1
#elif defined(__DragonFly__)
# define V8_OS_BSD 1
# define V8_OS_DRAGONFLYBSD 1
# define V8_OS_POSIX 1
#elif defined(__NetBSD__)
# define V8_OS_BSD 1
# define V8_OS_NETBSD 1
# define V8_OS_POSIX 1
#elif defined(__OpenBSD__)
# define V8_OS_BSD 1
# define V8_OS_OPENBSD 1
# define V8_OS_POSIX 1
114 115 116
#elif defined(__QNXNTO__)
# define V8_OS_POSIX 1
# define V8_OS_QNX 1
117 118 119 120 121
#elif defined(_WIN32)
# define V8_OS_WIN 1
#endif


122 123 124
// -----------------------------------------------------------------------------
// C library detection
//
125
//  V8_LIBC_MSVCRT  - MSVC libc
126 127 128
//  V8_LIBC_BIONIC  - Bionic libc
//  V8_LIBC_BSD     - BSD libc derivate
//  V8_LIBC_GLIBC   - GNU C library
129
//  V8_LIBC_UCLIBC  - uClibc
130 131 132 133 134 135 136
//
// Note that testing for libc must be done using #if not #ifdef. For example,
// to test for the GNU C library, use:
//  #if V8_LIBC_GLIBC
//   ...
//  #endif

137 138 139
#if defined (_MSC_VER)
# define V8_LIBC_MSVCRT 1
#elif defined(__BIONIC__)
140 141
# define V8_LIBC_BIONIC 1
# define V8_LIBC_BSD 1
142 143 144
#elif defined(__UCLIBC__)
// Must test for UCLIBC before GLIBC, as UCLIBC pretends to be GLIBC.
# define V8_LIBC_UCLIBC 1
145 146 147 148 149 150 151
#elif defined(__GLIBC__) || defined(__GNU_LIBRARY__)
# define V8_LIBC_GLIBC 1
#else
# define V8_LIBC_BSD V8_OS_BSD
#endif


152 153 154
// -----------------------------------------------------------------------------
// Compiler detection
//
155
//  V8_CC_GNU     - GCC, or clang in gcc mode
156
//  V8_CC_INTEL   - Intel C++
157
//  V8_CC_MINGW   - Minimalist GNU for Windows
158 159
//  V8_CC_MINGW32 - Minimalist GNU for Windows (mingw32)
//  V8_CC_MINGW64 - Minimalist GNU for Windows (mingw-w64)
160
//  V8_CC_MSVC    - Microsoft Visual C/C++, or clang in cl.exe mode
161 162 163 164
//
// C++11 feature detection
//
//  V8_HAS_CXX11_ALIGNAS        - alignas specifier supported
165
//  V8_HAS_CXX11_ALIGNOF        - alignof(type) operator supported
166 167 168
//
// Compiler-specific feature detection
//
169 170 171 172 173 174
//  V8_HAS___ALIGNOF                    - __alignof(type) operator supported
//  V8_HAS___ALIGNOF__                  - __alignof__(type) operator supported
//  V8_HAS_ATTRIBUTE_ALIGNED            - __attribute__((aligned(n))) supported
//  V8_HAS_ATTRIBUTE_ALWAYS_INLINE      - __attribute__((always_inline))
//                                        supported
//  V8_HAS_ATTRIBUTE_DEPRECATED         - __attribute__((deprecated)) supported
175
//  V8_HAS_ATTRIBUTE_NOINLINE           - __attribute__((noinline)) supported
176
//  V8_HAS_ATTRIBUTE_NORETURN           - __attribute__((noreturn)) supported
177
//  V8_HAS_ATTRIBUTE_UNUSED             - __attribute__((unused)) supported
178 179 180
//  V8_HAS_ATTRIBUTE_VISIBILITY         - __attribute__((visibility)) supported
//  V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT - __attribute__((warn_unused_result))
//                                        supported
181 182
//  V8_HAS_BUILTIN_CLZ                  - __builtin_clz() supported
//  V8_HAS_BUILTIN_CTZ                  - __builtin_ctz() supported
183
//  V8_HAS_BUILTIN_EXPECT               - __builtin_expect() supported
184
//  V8_HAS_BUILTIN_FRAME_ADDRESS        - __builtin_frame_address() supported
185
//  V8_HAS_BUILTIN_POPCOUNT             - __builtin_popcount() supported
186 187
//  V8_HAS_BUILTIN_SADD_OVERFLOW        - __builtin_sadd_overflow() supported
//  V8_HAS_BUILTIN_SSUB_OVERFLOW        - __builtin_ssub_overflow() supported
188
//  V8_HAS_BUILTIN_UADD_OVERFLOW        - __builtin_uadd_overflow() supported
189 190
//  V8_HAS_DECLSPEC_ALIGN               - __declspec(align(n)) supported
//  V8_HAS_DECLSPEC_DEPRECATED          - __declspec(deprecated) supported
191
//  V8_HAS_DECLSPEC_NOINLINE            - __declspec(noinline) supported
192
//  V8_HAS_DECLSPEC_SELECTANY           - __declspec(selectany) supported
193
//  V8_HAS_DECLSPEC_NORETURN            - __declspec(noreturn) supported
194 195 196 197 198 199 200
//  V8_HAS___FORCEINLINE                - __forceinline supported
//
// Note that testing for compilers and/or features must be done using #if
// not #ifdef. For example, to test for Intel C++ Compiler, use:
//  #if V8_CC_INTEL
//   ...
//  #endif
201 202 203

#if defined(__clang__)

204 205 206
#if defined(__GNUC__)  // Clang in gcc mode.
# define V8_CC_GNU 1
#endif
207

208 209 210 211 212
// Clang defines __alignof__ as alias for __alignof
# define V8_HAS___ALIGNOF 1
# define V8_HAS___ALIGNOF__ V8_HAS___ALIGNOF

# define V8_HAS_ATTRIBUTE_ALIGNED (__has_attribute(aligned))
213 214
# define V8_HAS_ATTRIBUTE_ALWAYS_INLINE (__has_attribute(always_inline))
# define V8_HAS_ATTRIBUTE_DEPRECATED (__has_attribute(deprecated))
215
# define V8_HAS_ATTRIBUTE_NOINLINE (__has_attribute(noinline))
216
# define V8_HAS_ATTRIBUTE_NORETURN (__has_attribute(noreturn))
217
# define V8_HAS_ATTRIBUTE_UNUSED (__has_attribute(unused))
218
# define V8_HAS_ATTRIBUTE_VISIBILITY (__has_attribute(visibility))
219 220
# define V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT \
    (__has_attribute(warn_unused_result))
221

222 223
# define V8_HAS_BUILTIN_CLZ (__has_builtin(__builtin_clz))
# define V8_HAS_BUILTIN_CTZ (__has_builtin(__builtin_ctz))
224
# define V8_HAS_BUILTIN_EXPECT (__has_builtin(__builtin_expect))
225
# define V8_HAS_BUILTIN_FRAME_ADDRESS (__has_builtin(__builtin_frame_address))
226
# define V8_HAS_BUILTIN_POPCOUNT (__has_builtin(__builtin_popcount))
227 228
# define V8_HAS_BUILTIN_SADD_OVERFLOW (__has_builtin(__builtin_sadd_overflow))
# define V8_HAS_BUILTIN_SSUB_OVERFLOW (__has_builtin(__builtin_ssub_overflow))
229
# define V8_HAS_BUILTIN_UADD_OVERFLOW (__has_builtin(__builtin_uadd_overflow))
230 231 232 233 234 235

# define V8_HAS_CXX11_ALIGNAS (__has_feature(cxx_alignas))

#elif defined(__GNUC__)

# define V8_CC_GNU 1
236 237 238 239 240 241 242 243 244
# if defined(__INTEL_COMPILER)  // Intel C++ also masquerades as GCC 3.2.0
#  define V8_CC_INTEL 1
# endif
# if defined(__MINGW32__)
#  define V8_CC_MINGW32 1
# endif
# if defined(__MINGW64__)
#  define V8_CC_MINGW64 1
# endif
245
# define V8_CC_MINGW (V8_CC_MINGW32 || V8_CC_MINGW64)
246

247 248 249
# define V8_HAS___ALIGNOF__ (V8_GNUC_PREREQ(4, 3, 0))

# define V8_HAS_ATTRIBUTE_ALIGNED (V8_GNUC_PREREQ(2, 95, 0))
250 251 252 253
// always_inline is available in gcc 4.0 but not very reliable until 4.4.
// Works around "sorry, unimplemented: inlining failed" build errors with
// older compilers.
# define V8_HAS_ATTRIBUTE_ALWAYS_INLINE (V8_GNUC_PREREQ(4, 4, 0))
254
# define V8_HAS_ATTRIBUTE_DEPRECATED (V8_GNUC_PREREQ(3, 4, 0))
255
# define V8_HAS_ATTRIBUTE_DEPRECATED_MESSAGE (V8_GNUC_PREREQ(4, 5, 0))
256
# define V8_HAS_ATTRIBUTE_NOINLINE (V8_GNUC_PREREQ(3, 4, 0))
257
# define V8_HAS_ATTRIBUTE_NORETURN (V8_GNUC_PREREQ(2, 5, 0))
258
# define V8_HAS_ATTRIBUTE_UNUSED (V8_GNUC_PREREQ(2, 95, 0))
259
# define V8_HAS_ATTRIBUTE_VISIBILITY (V8_GNUC_PREREQ(4, 3, 0))
260 261
# define V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT \
    (!V8_CC_INTEL && V8_GNUC_PREREQ(4, 1, 0))
262

263 264
# define V8_HAS_BUILTIN_CLZ (V8_GNUC_PREREQ(3, 4, 0))
# define V8_HAS_BUILTIN_CTZ (V8_GNUC_PREREQ(3, 4, 0))
265
# define V8_HAS_BUILTIN_EXPECT (V8_GNUC_PREREQ(2, 96, 0))
266
# define V8_HAS_BUILTIN_FRAME_ADDRESS (V8_GNUC_PREREQ(2, 96, 0))
267
# define V8_HAS_BUILTIN_POPCOUNT (V8_GNUC_PREREQ(3, 4, 0))
268

jfb's avatar
jfb committed
269
# if __cplusplus >= 201103L
270
#  define V8_HAS_CXX11_ALIGNAS (V8_GNUC_PREREQ(4, 8, 0))
271
#  define V8_HAS_CXX11_ALIGNOF (V8_GNUC_PREREQ(4, 8, 0))
272
# endif
273
#endif
274

275
#if defined(_MSC_VER)
276
# define V8_CC_MSVC 1
277 278
# define V8_HAS___ALIGNOF 1

279
# define V8_HAS_DECLSPEC_ALIGN 1
280
# define V8_HAS_DECLSPEC_DEPRECATED 1
281
# define V8_HAS_DECLSPEC_NOINLINE 1
282
# define V8_HAS_DECLSPEC_SELECTANY 1
283
# define V8_HAS_DECLSPEC_NORETURN 1
284 285 286 287 288 289 290 291 292 293

# define V8_HAS___FORCEINLINE 1

#endif


// -----------------------------------------------------------------------------
// Helper macros

// A macro used to make better inlining. Don't bother for debug builds.
294 295
// Use like:
//   V8_INLINE int GetZero() { return 0; }
296
#if !defined(DEBUG) && V8_HAS_ATTRIBUTE_ALWAYS_INLINE
297
# define V8_INLINE inline __attribute__((always_inline))
298
#elif !defined(DEBUG) && V8_HAS___FORCEINLINE
299
# define V8_INLINE __forceinline
300
#else
301
# define V8_INLINE inline
302 303 304
#endif


305 306
// A macro used to tell the compiler to never inline a particular function.
// Don't bother for debug builds.
307 308
// Use like:
//   V8_NOINLINE int GetMinusOne() { return -1; }
309
#if !defined(DEBUG) && V8_HAS_ATTRIBUTE_NOINLINE
310
# define V8_NOINLINE __attribute__((noinline))
311
#elif !defined(DEBUG) && V8_HAS_DECLSPEC_NOINLINE
312
# define V8_NOINLINE __declspec(noinline)
313
#else
314
# define V8_NOINLINE /* NOT SUPPORTED */
315 316 317
#endif


318 319 320 321 322 323 324 325 326 327 328 329
// A macro used to tell the compiler that a particular function never returns.
// Use like:
//   V8_NORETURN void MyAbort() { abort(); }
#if V8_HAS_ATTRIBUTE_NORETURN
# define V8_NORETURN __attribute__((noreturn))
#elif HAS_DECLSPEC_NORETURN
# define V8_NORETURN __declspec(noreturn)
#else
# define V8_NORETURN /* NOT SUPPORTED */
#endif


330
// A macro (V8_DEPRECATED) to mark classes or functions as deprecated.
331
#if defined(V8_DEPRECATION_WARNINGS) && V8_HAS_ATTRIBUTE_DEPRECATED_MESSAGE
332 333
#define V8_DEPRECATED(message, declarator) \
  declarator __attribute__((deprecated(message)))
334
#elif defined(V8_DEPRECATION_WARNINGS) && V8_HAS_ATTRIBUTE_DEPRECATED
335 336
#define V8_DEPRECATED(message, declarator) \
  declarator __attribute__((deprecated))
337
#elif defined(V8_DEPRECATION_WARNINGS) && V8_HAS_DECLSPEC_DEPRECATED
338
#define V8_DEPRECATED(message, declarator) __declspec(deprecated) declarator
339
#else
340
#define V8_DEPRECATED(message, declarator) declarator
341 342 343
#endif


344 345 346 347 348 349 350 351 352 353 354
// A macro (V8_DEPRECATE_SOON) to make it easier to see what will be deprecated.
#if defined(V8_IMMINENT_DEPRECATION_WARNINGS) && \
    V8_HAS_ATTRIBUTE_DEPRECATED_MESSAGE
#define V8_DEPRECATE_SOON(message, declarator) \
  declarator __attribute__((deprecated(message)))
#elif defined(V8_IMMINENT_DEPRECATION_WARNINGS) && V8_HAS_ATTRIBUTE_DEPRECATED
#define V8_DEPRECATE_SOON(message, declarator) \
  declarator __attribute__((deprecated))
#elif defined(V8_IMMINENT_DEPRECATION_WARNINGS) && V8_HAS_DECLSPEC_DEPRECATED
#define V8_DEPRECATE_SOON(message, declarator) __declspec(deprecated) declarator
#else
355
#define V8_DEPRECATE_SOON(message, declarator) declarator
356
#endif
357 358


359 360 361 362 363 364 365 366 367 368 369 370
// A macro to provide the compiler with branch prediction information.
#if V8_HAS_BUILTIN_EXPECT
# define V8_UNLIKELY(condition) (__builtin_expect(!!(condition), 0))
# define V8_LIKELY(condition) (__builtin_expect(!!(condition), 1))
#else
# define V8_UNLIKELY(condition) (condition)
# define V8_LIKELY(condition) (condition)
#endif


// This macro allows to specify memory alignment for structs, classes, etc.
// Use like:
371 372
//   class V8_ALIGNED(16) MyClass { ... };
//   V8_ALIGNED(32) int array[42];
373
#if V8_HAS_CXX11_ALIGNAS
374 375 376
# define V8_ALIGNED(n) alignas(n)
#elif V8_HAS_ATTRIBUTE_ALIGNED
# define V8_ALIGNED(n) __attribute__((aligned(n)))
377
#elif V8_HAS_DECLSPEC_ALIGN
378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412
# define V8_ALIGNED(n) __declspec(align(n))
#else
# define V8_ALIGNED(n) /* NOT SUPPORTED */
#endif


// This macro is similar to V8_ALIGNED(), but takes a type instead of size
// in bytes. If the compiler does not supports using the alignment of the
// |type|, it will align according to the |alignment| instead. For example,
// Visual Studio C++ cannot combine __declspec(align) and __alignof. The
// |alignment| must be a literal that is used as a kind of worst-case fallback
// alignment.
// Use like:
//   struct V8_ALIGNAS(AnotherClass, 16) NewClass { ... };
//   V8_ALIGNAS(double, 8) int array[100];
#if V8_HAS_CXX11_ALIGNAS
# define V8_ALIGNAS(type, alignment) alignas(type)
#elif V8_HAS___ALIGNOF__ && V8_HAS_ATTRIBUTE_ALIGNED
# define V8_ALIGNAS(type, alignment) __attribute__((aligned(__alignof__(type))))
#else
# define V8_ALIGNAS(type, alignment) V8_ALIGNED(alignment)
#endif


// This macro returns alignment in bytes (an integer power of two) required for
// any instance of the given type, which is either complete type, an array type,
// or a reference type.
// Use like:
//   size_t alignment = V8_ALIGNOF(double);
#if V8_HAS_CXX11_ALIGNOF
# define V8_ALIGNOF(type) alignof(type)
#elif V8_HAS___ALIGNOF
# define V8_ALIGNOF(type) __alignof(type)
#elif V8_HAS___ALIGNOF__
# define V8_ALIGNOF(type) __alignof__(type)
413
#else
414 415 416 417 418
// Note that alignment of a type within a struct can be less than the
// alignment of the type stand-alone (because of ancient ABIs), so this
// should only be used as a last resort.
namespace v8 { template <typename T> class AlignOfHelper { char c; T t; }; }
# define V8_ALIGNOF(type) (sizeof(::v8::AlignOfHelper<type>) - sizeof(type))
419 420
#endif

421 422 423 424 425 426 427 428 429
// Annotate a function indicating the caller must examine the return value.
// Use like:
//   int foo() WARN_UNUSED_RESULT;
#if V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT
#define V8_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
#else
#define V8_WARN_UNUSED_RESULT /* NOT SUPPORTED */
#endif

430 431
// clang-format on

432
#endif  // V8CONFIG_H_