v8config.h 14.9 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
// Operating system detection (host)
58 59 60 61 62 63
//
//  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
scottmg's avatar
scottmg committed
64
//  V8_OS_FUCHSIA       - Fuchsia
65 66
//  V8_OS_LINUX         - Linux
//  V8_OS_MACOSX        - Mac OS X
67
//  V8_OS_IOS           - iOS
68 69 70
//  V8_OS_NETBSD        - NetBSD
//  V8_OS_OPENBSD       - OpenBSD
//  V8_OS_POSIX         - POSIX compatible (mostly everything except Windows)
71
//  V8_OS_QNX           - QNX Neutrino
72
//  V8_OS_SOLARIS       - Sun Solaris and OpenSolaris
73
//  V8_OS_AIX           - AIX
74 75 76 77 78 79 80 81 82 83
//  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
84 85 86
# if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
#  define V8_OS_IOS 1
# endif  // defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
87 88 89 90 91 92 93 94 95
#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
96 97 98
#elif defined(_AIX)
#define V8_OS_POSIX 1
#define V8_OS_AIX 1
99 100 101 102
#elif defined(__FreeBSD__)
# define V8_OS_BSD 1
# define V8_OS_FREEBSD 1
# define V8_OS_POSIX 1
scottmg's avatar
scottmg committed
103 104 105
#elif defined(__Fuchsia__)
# define V8_OS_FUCHSIA 1
# define V8_OS_POSIX 1
106 107 108 109 110 111 112 113 114 115 116 117
#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
118 119 120
#elif defined(__QNXNTO__)
# define V8_OS_POSIX 1
# define V8_OS_QNX 1
121 122 123 124
#elif defined(_WIN32)
# define V8_OS_WIN 1
#endif

125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
// -----------------------------------------------------------------------------
// Operating system detection (target)
//
//  V8_TARGET_OS_ANDROID
//  V8_TARGET_OS_FUCHSIA
//  V8_TARGET_OS_IOS
//  V8_TARGET_OS_LINUX
//  V8_TARGET_OS_MACOSX
//  V8_TARGET_OS_WIN
//
// If not set explicitly, these fall back to corresponding V8_OS_ values.

#ifdef V8_HAVE_TARGET_OS

// The target OS is provided, just check that at least one known value is set.
# if !defined(V8_TARGET_OS_ANDROID) \
  && !defined(V8_TARGET_OS_FUCHSIA) \
  && !defined(V8_TARGET_OS_IOS) \
  && !defined(V8_TARGET_OS_LINUX) \
  && !defined(V8_TARGET_OS_MACOSX) \
  && !defined(V8_TARGET_OS_WIN)
#  error No known target OS defined.
# endif

#else  // V8_HAVE_TARGET_OS

# if defined(V8_TARGET_OS_ANDROID) \
  || defined(V8_TARGET_OS_FUCHSIA) \
  || defined(V8_TARGET_OS_IOS) \
  || defined(V8_TARGET_OS_LINUX) \
  || defined(V8_TARGET_OS_MACOSX) \
  || defined(V8_TARGET_OS_WIN)
#  error A target OS is defined but V8_HAVE_TARGET_OS is unset.
# endif

// Fall back to the detected host OS.
#ifdef V8_OS_ANDROID
# define V8_TARGET_OS_ANDROID
#endif

#ifdef V8_OS_FUCHSIA
# define V8_TARGET_OS_FUCHSIA
#endif

#ifdef V8_OS_IOS
# define V8_TARGET_OS_IOS
#endif

#ifdef V8_OS_LINUX
# define V8_TARGET_OS_LINUX
#endif

#ifdef V8_OS_MACOSX
# define V8_TARGET_OS_MACOSX
#endif

#ifdef V8_OS_WIN
# define V8_TARGET_OS_WIN
#endif

#endif  // V8_HAVE_TARGET_OS
186

187 188 189
// -----------------------------------------------------------------------------
// C library detection
//
190
//  V8_LIBC_MSVCRT  - MSVC libc
191 192 193
//  V8_LIBC_BIONIC  - Bionic libc
//  V8_LIBC_BSD     - BSD libc derivate
//  V8_LIBC_GLIBC   - GNU C library
194
//  V8_LIBC_UCLIBC  - uClibc
195 196 197 198 199 200 201
//
// 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

202 203 204
#if defined (_MSC_VER)
# define V8_LIBC_MSVCRT 1
#elif defined(__BIONIC__)
205 206
# define V8_LIBC_BIONIC 1
# define V8_LIBC_BSD 1
207 208 209
#elif defined(__UCLIBC__)
// Must test for UCLIBC before GLIBC, as UCLIBC pretends to be GLIBC.
# define V8_LIBC_UCLIBC 1
210 211 212 213 214 215 216
#elif defined(__GLIBC__) || defined(__GNU_LIBRARY__)
# define V8_LIBC_GLIBC 1
#else
# define V8_LIBC_BSD V8_OS_BSD
#endif


217 218 219
// -----------------------------------------------------------------------------
// Compiler detection
//
220
//  V8_CC_GNU     - GCC, or clang in gcc mode
221
//  V8_CC_INTEL   - Intel C++
222
//  V8_CC_MINGW   - Minimalist GNU for Windows
223 224
//  V8_CC_MINGW32 - Minimalist GNU for Windows (mingw32)
//  V8_CC_MINGW64 - Minimalist GNU for Windows (mingw-w64)
225
//  V8_CC_MSVC    - Microsoft Visual C/C++, or clang in cl.exe mode
226 227 228 229 230
//
// C++11 feature detection
//
// Compiler-specific feature detection
//
231 232
//  V8_HAS_ATTRIBUTE_ALWAYS_INLINE      - __attribute__((always_inline))
//                                        supported
233
//  V8_HAS_ATTRIBUTE_NONNULL            - __attribute__((nonnull)) supported
234
//  V8_HAS_ATTRIBUTE_NOINLINE           - __attribute__((noinline)) supported
235
//  V8_HAS_ATTRIBUTE_UNUSED             - __attribute__((unused)) supported
236 237 238
//  V8_HAS_ATTRIBUTE_VISIBILITY         - __attribute__((visibility)) supported
//  V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT - __attribute__((warn_unused_result))
//                                        supported
239 240 241
//  V8_HAS_BUILTIN_BSWAP16              - __builtin_bswap16() supported
//  V8_HAS_BUILTIN_BSWAP32              - __builtin_bswap32() supported
//  V8_HAS_BUILTIN_BSWAP64              - __builtin_bswap64() supported
242 243
//  V8_HAS_BUILTIN_CLZ                  - __builtin_clz() supported
//  V8_HAS_BUILTIN_CTZ                  - __builtin_ctz() supported
244
//  V8_HAS_BUILTIN_EXPECT               - __builtin_expect() supported
245
//  V8_HAS_BUILTIN_FRAME_ADDRESS        - __builtin_frame_address() supported
246
//  V8_HAS_BUILTIN_POPCOUNT             - __builtin_popcount() supported
247 248
//  V8_HAS_BUILTIN_SADD_OVERFLOW        - __builtin_sadd_overflow() supported
//  V8_HAS_BUILTIN_SSUB_OVERFLOW        - __builtin_ssub_overflow() supported
249
//  V8_HAS_BUILTIN_UADD_OVERFLOW        - __builtin_uadd_overflow() supported
250 251
//  V8_HAS_COMPUTED_GOTO                - computed goto/labels as values
//                                        supported
252
//  V8_HAS_DECLSPEC_NOINLINE            - __declspec(noinline) supported
253
//  V8_HAS_DECLSPEC_SELECTANY           - __declspec(selectany) supported
254 255 256 257 258 259 260
//  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
261 262 263

#if defined(__clang__)

264 265 266
#if defined(__GNUC__)  // Clang in gcc mode.
# define V8_CC_GNU 1
#endif
267

268
# define V8_HAS_ATTRIBUTE_ALWAYS_INLINE (__has_attribute(always_inline))
269
# define V8_HAS_ATTRIBUTE_NONNULL (__has_attribute(nonnull))
270
# define V8_HAS_ATTRIBUTE_NOINLINE (__has_attribute(noinline))
271
# define V8_HAS_ATTRIBUTE_UNUSED (__has_attribute(unused))
272
# define V8_HAS_ATTRIBUTE_VISIBILITY (__has_attribute(visibility))
273 274
# define V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT \
    (__has_attribute(warn_unused_result))
275

276
# define V8_HAS_BUILTIN_ASSUME_ALIGNED (__has_builtin(__builtin_assume_aligned))
277 278 279
# define V8_HAS_BUILTIN_BSWAP16 (__has_builtin(__builtin_bswap16))
# define V8_HAS_BUILTIN_BSWAP32 (__has_builtin(__builtin_bswap32))
# define V8_HAS_BUILTIN_BSWAP64 (__has_builtin(__builtin_bswap64))
280 281
# define V8_HAS_BUILTIN_CLZ (__has_builtin(__builtin_clz))
# define V8_HAS_BUILTIN_CTZ (__has_builtin(__builtin_ctz))
282
# define V8_HAS_BUILTIN_EXPECT (__has_builtin(__builtin_expect))
283
# define V8_HAS_BUILTIN_FRAME_ADDRESS (__has_builtin(__builtin_frame_address))
284
# define V8_HAS_BUILTIN_POPCOUNT (__has_builtin(__builtin_popcount))
285 286
# define V8_HAS_BUILTIN_SADD_OVERFLOW (__has_builtin(__builtin_sadd_overflow))
# define V8_HAS_BUILTIN_SSUB_OVERFLOW (__has_builtin(__builtin_ssub_overflow))
287
# define V8_HAS_BUILTIN_UADD_OVERFLOW (__has_builtin(__builtin_uadd_overflow))
288

289 290 291 292
// Clang has no __has_feature for computed gotos.
// GCC doc: https://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html
# define V8_HAS_COMPUTED_GOTO 1

293 294 295
// Whether constexpr has full C++14 semantics, in particular that non-constexpr
// code is allowed as long as it's not executed for any constexpr instantiation.
# define V8_HAS_CXX14_CONSTEXPR 1
296

297 298 299
#elif defined(__GNUC__)

# define V8_CC_GNU 1
300 301 302 303 304 305 306 307 308
# 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
309
# define V8_CC_MINGW (V8_CC_MINGW32 || V8_CC_MINGW64)
310

311 312 313
// 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.
314 315 316 317 318 319 320 321 322 323 324 325
# define V8_HAS_ATTRIBUTE_ALWAYS_INLINE 1
# define V8_HAS_ATTRIBUTE_NOINLINE 1
# define V8_HAS_ATTRIBUTE_UNUSED 1
# define V8_HAS_ATTRIBUTE_VISIBILITY 1
# define V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT (!V8_CC_INTEL)

# define V8_HAS_BUILTIN_ASSUME_ALIGNED 1
# define V8_HAS_BUILTIN_CLZ 1
# define V8_HAS_BUILTIN_CTZ 1
# define V8_HAS_BUILTIN_EXPECT 1
# define V8_HAS_BUILTIN_FRAME_ADDRESS 1
# define V8_HAS_BUILTIN_POPCOUNT 1
326

327
// GCC doc: https://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html
328
#define V8_HAS_COMPUTED_GOTO 1
329

330 331 332 333 334
// Whether constexpr has full C++14 semantics, in particular that non-constexpr
// code is allowed as long as it's not executed for any constexpr instantiation.
// GCC only supports this since version 6.
# define V8_HAS_CXX14_CONSTEXPR (V8_GNUC_PREREQ(6, 0, 0))

335
#endif
336

337
#if defined(_MSC_VER)
338
# define V8_CC_MSVC 1
339

340
# define V8_HAS_DECLSPEC_NOINLINE 1
341
# define V8_HAS_DECLSPEC_SELECTANY 1
342 343 344 345 346 347 348 349 350 351

# define V8_HAS___FORCEINLINE 1

#endif


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

// A macro used to make better inlining. Don't bother for debug builds.
352 353
// Use like:
//   V8_INLINE int GetZero() { return 0; }
354
#if !defined(DEBUG) && V8_HAS_ATTRIBUTE_ALWAYS_INLINE
355
# define V8_INLINE inline __attribute__((always_inline))
356
#elif !defined(DEBUG) && V8_HAS___FORCEINLINE
357
# define V8_INLINE __forceinline
358
#else
359
# define V8_INLINE inline
360 361
#endif

362 363 364 365
#if V8_HAS_BUILTIN_ASSUME_ALIGNED
# define V8_ASSUME_ALIGNED(ptr, alignment) \
  __builtin_assume_aligned((ptr), (alignment))
#else
366
# define V8_ASSUME_ALIGNED(ptr, alignment) (ptr)
367
#endif
368

369 370 371 372 373 374 375 376 377 378 379

// A macro to mark specific arguments as non-null.
// Use like:
//   int add(int* x, int y, int* z) V8_NONNULL(1, 3) { return *x + y + *z; }
#if V8_HAS_ATTRIBUTE_NONNULL
# define V8_NONNULL(...) __attribute__((nonnull(__VA_ARGS__)))
#else
# define V8_NONNULL(...) /* NOT SUPPORTED */
#endif


380
// A macro used to tell the compiler to never inline a particular function.
381 382
// Use like:
//   V8_NOINLINE int GetMinusOne() { return -1; }
383
#if V8_HAS_ATTRIBUTE_NOINLINE
384
# define V8_NOINLINE __attribute__((noinline))
385
#elif V8_HAS_DECLSPEC_NOINLINE
386
# define V8_NOINLINE __declspec(noinline)
387
#else
388
# define V8_NOINLINE /* NOT SUPPORTED */
389 390 391
#endif


392
// A macro (V8_DEPRECATED) to mark classes or functions as deprecated.
393 394
#if defined(V8_DEPRECATION_WARNINGS)
# define V8_DEPRECATED(message) [[deprecated(message)]]
395
#else
396
# define V8_DEPRECATED(message)
397 398 399
#endif


400
// A macro (V8_DEPRECATE_SOON) to make it easier to see what will be deprecated.
401 402
#if defined(V8_IMMINENT_DEPRECATION_WARNINGS)
# define V8_DEPRECATE_SOON(message) [[deprecated(message)]]
403
#else
404
# define V8_DEPRECATE_SOON(message)
405
#endif
406 407


408 409 410 411 412 413 414 415 416
#if defined(__GNUC__) && !defined(__clang__) && (__GNUC__ < 6)
# define V8_ENUM_DEPRECATED(message)
# define V8_ENUM_DEPRECATE_SOON(message)
#else
# define V8_ENUM_DEPRECATED(message) V8_DEPRECATED(message)
# define V8_ENUM_DEPRECATE_SOON(message) V8_DEPRECATE_SOON(message)
#endif


417 418 419 420 421 422 423 424 425 426
// 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


427 428
// Annotate a function indicating the caller must examine the return value.
// Use like:
429
//   int foo() V8_WARN_UNUSED_RESULT;
430 431 432 433 434 435
#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

436 437 438 439 440 441
#if defined(BUILDING_V8_SHARED) && defined(USING_V8_SHARED)
#error Inconsistent build configuration: To build the V8 shared library \
set BUILDING_V8_SHARED, to include its headers for linking against the \
V8 shared library set USING_V8_SHARED.
#endif

442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471
#ifdef V8_OS_WIN

// Setup for Windows DLL export/import. When building the V8 DLL the
// BUILDING_V8_SHARED needs to be defined. When building a program which uses
// the V8 DLL USING_V8_SHARED needs to be defined. When either building the V8
// static library or building a program which uses the V8 static library neither
// BUILDING_V8_SHARED nor USING_V8_SHARED should be defined.
#ifdef BUILDING_V8_SHARED
# define V8_EXPORT __declspec(dllexport)
#elif USING_V8_SHARED
# define V8_EXPORT __declspec(dllimport)
#else
# define V8_EXPORT
#endif  // BUILDING_V8_SHARED

#else  // V8_OS_WIN

// Setup for Linux shared library export.
#if V8_HAS_ATTRIBUTE_VISIBILITY
# ifdef BUILDING_V8_SHARED
#  define V8_EXPORT __attribute__ ((visibility("default")))
# else
#  define V8_EXPORT
# endif
#else
# define V8_EXPORT
#endif

#endif  // V8_OS_WIN

472 473
// clang-format on

474
#endif  // V8CONFIG_H_