1 // Copyright 2013 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef V8CONFIG_H_ 6 #define V8CONFIG_H_ 7 8 #ifdef V8_GN_HEADER 9 #if __cplusplus >= 201703L && !__has_include("v8-gn.h") 10 #error Missing v8-gn.h. The configuration for v8 is missing from the include \ 11 path. Add it with -I<path> to the command line 12 #endif 13 #include "v8-gn.h" // NOLINT(build/include_directory) 14 #endif 15 16 // clang-format off 17 18 // Platform headers for feature detection below. 19 #if defined(__ANDROID__) 20 # include <sys/cdefs.h> 21 #elif defined(__APPLE__) 22 # include <TargetConditionals.h> 23 #elif defined(__linux__) 24 # include <features.h> 25 #endif 26 27 28 // This macro allows to test for the version of the GNU C library (or 29 // a compatible C library that masquerades as glibc). It evaluates to 30 // 0 if libc is not GNU libc or compatible. 31 // Use like: 32 // #if V8_GLIBC_PREREQ(2, 3) 33 // ... 34 // #endif 35 #if defined(__GLIBC__) && defined(__GLIBC_MINOR__) 36 # define V8_GLIBC_PREREQ(major, minor) \ 37 ((__GLIBC__ * 100 + __GLIBC_MINOR__) >= ((major) * 100 + (minor))) 38 #else 39 # define V8_GLIBC_PREREQ(major, minor) 0 40 #endif 41 42 43 // This macro allows to test for the version of the GNU C++ compiler. 44 // Note that this also applies to compilers that masquerade as GCC, 45 // for example clang and the Intel C++ compiler for Linux. 46 // Use like: 47 // #if V8_GNUC_PREREQ(4, 3, 1) 48 // ... 49 // #endif 50 #if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) 51 # define V8_GNUC_PREREQ(major, minor, patchlevel) \ 52 ((__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) >= \ 53 ((major) * 10000 + (minor) * 100 + (patchlevel))) 54 #elif defined(__GNUC__) && defined(__GNUC_MINOR__) 55 # define V8_GNUC_PREREQ(major, minor, patchlevel) \ 56 ((__GNUC__ * 10000 + __GNUC_MINOR__ * 100) >= \ 57 ((major) * 10000 + (minor) * 100 + (patchlevel))) 58 #else 59 # define V8_GNUC_PREREQ(major, minor, patchlevel) 0 60 #endif 61 62 63 64 // ----------------------------------------------------------------------------- 65 // Operating system detection (host) 66 // 67 // V8_OS_ANDROID - Android 68 // V8_OS_BSD - BSDish (macOS, Net/Free/Open/DragonFlyBSD) 69 // V8_OS_CYGWIN - Cygwin 70 // V8_OS_DRAGONFLYBSD - DragonFlyBSD 71 // V8_OS_FREEBSD - FreeBSD 72 // V8_OS_FUCHSIA - Fuchsia 73 // V8_OS_LINUX - Linux (Android, ChromeOS, Linux, ...) 74 // V8_OS_DARWIN - Darwin (macOS, iOS) 75 // V8_OS_MACOS - macOS 76 // V8_OS_IOS - iOS 77 // V8_OS_NETBSD - NetBSD 78 // V8_OS_OPENBSD - OpenBSD 79 // V8_OS_POSIX - POSIX compatible (mostly everything except Windows) 80 // V8_OS_QNX - QNX Neutrino 81 // V8_OS_SOLARIS - Sun Solaris and OpenSolaris 82 // V8_OS_STARBOARD - Starboard (platform abstraction for Cobalt) 83 // V8_OS_AIX - AIX 84 // V8_OS_WIN - Microsoft Windows 85 86 #if defined(__ANDROID__) 87 # define V8_OS_ANDROID 1 88 # define V8_OS_LINUX 1 89 # define V8_OS_POSIX 1 90 # define V8_OS_STRING "android" 91 92 #elif defined(__APPLE__) 93 # define V8_OS_POSIX 1 94 # define V8_OS_BSD 1 95 # define V8_OS_DARWIN 1 96 # if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE 97 # define V8_OS_IOS 1 98 # define V8_OS_STRING "ios" 99 # else 100 # define V8_OS_MACOS 1 101 # define V8_OS_STRING "macos" 102 # endif // defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE 103 104 #elif defined(__CYGWIN__) 105 # define V8_OS_CYGWIN 1 106 # define V8_OS_POSIX 1 107 # define V8_OS_STRING "cygwin" 108 109 #elif defined(__linux__) 110 # define V8_OS_LINUX 1 111 # define V8_OS_POSIX 1 112 # define V8_OS_STRING "linux" 113 114 #elif defined(__sun) 115 # define V8_OS_POSIX 1 116 # define V8_OS_SOLARIS 1 117 # define V8_OS_STRING "sun" 118 119 #elif defined(STARBOARD) 120 # define V8_OS_STARBOARD 1 121 # define V8_OS_STRING "starboard" 122 123 #elif defined(_AIX) 124 # define V8_OS_POSIX 1 125 # define V8_OS_AIX 1 126 # define V8_OS_STRING "aix" 127 128 #elif defined(__FreeBSD__) 129 # define V8_OS_BSD 1 130 # define V8_OS_FREEBSD 1 131 # define V8_OS_POSIX 1 132 # define V8_OS_STRING "freebsd" 133 134 #elif defined(__Fuchsia__) 135 # define V8_OS_FUCHSIA 1 136 # define V8_OS_POSIX 1 137 # define V8_OS_STRING "fuchsia" 138 139 #elif defined(__DragonFly__) 140 # define V8_OS_BSD 1 141 # define V8_OS_DRAGONFLYBSD 1 142 # define V8_OS_POSIX 1 143 # define V8_OS_STRING "dragonflybsd" 144 145 #elif defined(__NetBSD__) 146 # define V8_OS_BSD 1 147 # define V8_OS_NETBSD 1 148 # define V8_OS_POSIX 1 149 # define V8_OS_STRING "netbsd" 150 151 #elif defined(__OpenBSD__) 152 # define V8_OS_BSD 1 153 # define V8_OS_OPENBSD 1 154 # define V8_OS_POSIX 1 155 # define V8_OS_STRING "openbsd" 156 157 #elif defined(__QNXNTO__) 158 # define V8_OS_POSIX 1 159 # define V8_OS_QNX 1 160 # define V8_OS_STRING "qnx" 161 162 #elif defined(_WIN32) 163 # define V8_OS_WIN 1 164 # define V8_OS_STRING "windows" 165 #endif 166 167 // ----------------------------------------------------------------------------- 168 // Operating system detection (target) 169 // 170 // V8_TARGET_OS_ANDROID 171 // V8_TARGET_OS_FUCHSIA 172 // V8_TARGET_OS_IOS 173 // V8_TARGET_OS_LINUX 174 // V8_TARGET_OS_MACOS 175 // V8_TARGET_OS_WIN 176 // V8_TARGET_OS_CHROMEOS 177 // 178 // If not set explicitly, these fall back to corresponding V8_OS_ values. 179 180 #ifdef V8_HAVE_TARGET_OS 181 182 // The target OS is provided, just check that at least one known value is set. 183 # if !defined(V8_TARGET_OS_ANDROID) \ 184 && !defined(V8_TARGET_OS_FUCHSIA) \ 185 && !defined(V8_TARGET_OS_IOS) \ 186 && !defined(V8_TARGET_OS_LINUX) \ 187 && !defined(V8_TARGET_OS_MACOS) \ 188 && !defined(V8_TARGET_OS_WIN) \ 189 && !defined(V8_TARGET_OS_CHROMEOS) 190 # error No known target OS defined. 191 # endif 192 193 #else // V8_HAVE_TARGET_OS 194 195 # if defined(V8_TARGET_OS_ANDROID) \ 196 || defined(V8_TARGET_OS_FUCHSIA) \ 197 || defined(V8_TARGET_OS_IOS) \ 198 || defined(V8_TARGET_OS_LINUX) \ 199 || defined(V8_TARGET_OS_MACOS) \ 200 || defined(V8_TARGET_OS_WIN) \ 201 || defined(V8_TARGET_OS_CHROMEOS) 202 # error A target OS is defined but V8_HAVE_TARGET_OS is unset. 203 # endif 204 205 // Fall back to the detected host OS. 206 #ifdef V8_OS_ANDROID 207 # define V8_TARGET_OS_ANDROID 208 #endif 209 210 #ifdef V8_OS_FUCHSIA 211 # define V8_TARGET_OS_FUCHSIA 212 #endif 213 214 #ifdef V8_OS_IOS 215 # define V8_TARGET_OS_IOS 216 #endif 217 218 #ifdef V8_OS_LINUX 219 # define V8_TARGET_OS_LINUX 220 #endif 221 222 #ifdef V8_OS_MACOS 223 # define V8_TARGET_OS_MACOS 224 #endif 225 226 #ifdef V8_OS_WIN 227 # define V8_TARGET_OS_WIN 228 #endif 229 230 #endif // V8_HAVE_TARGET_OS 231 232 #if defined(V8_TARGET_OS_ANDROID) 233 # define V8_TARGET_OS_STRING "android" 234 #elif defined(V8_TARGET_OS_FUCHSIA) 235 # define V8_TARGET_OS_STRING "fuchsia" 236 #elif defined(V8_TARGET_OS_IOS) 237 # define V8_TARGET_OS_STRING "ios" 238 #elif defined(V8_TARGET_OS_LINUX) 239 # define V8_TARGET_OS_STRING "linux" 240 #elif defined(V8_TARGET_OS_MACOS) 241 # define V8_TARGET_OS_STRING "macos" 242 #elif defined(V8_TARGET_OS_WINDOWS) 243 # define V8_TARGET_OS_STRING "windows" 244 #else 245 # define V8_TARGET_OS_STRING "unknown" 246 #endif 247 248 // ----------------------------------------------------------------------------- 249 // C library detection 250 // 251 // V8_LIBC_MSVCRT - MSVC libc 252 // V8_LIBC_BIONIC - Bionic libc 253 // V8_LIBC_BSD - BSD libc derivate 254 // V8_LIBC_GLIBC - GNU C library 255 // V8_LIBC_UCLIBC - uClibc 256 // 257 // Note that testing for libc must be done using #if not #ifdef. For example, 258 // to test for the GNU C library, use: 259 // #if V8_LIBC_GLIBC 260 // ... 261 // #endif 262 263 #if defined (_MSC_VER) 264 # define V8_LIBC_MSVCRT 1 265 #elif defined(__BIONIC__) 266 # define V8_LIBC_BIONIC 1 267 # define V8_LIBC_BSD 1 268 #elif defined(__UCLIBC__) 269 // Must test for UCLIBC before GLIBC, as UCLIBC pretends to be GLIBC. 270 # define V8_LIBC_UCLIBC 1 271 #elif defined(__GLIBC__) || defined(__GNU_LIBRARY__) 272 # define V8_LIBC_GLIBC 1 273 #else 274 # define V8_LIBC_BSD V8_OS_BSD 275 #endif 276 277 278 // ----------------------------------------------------------------------------- 279 // Compiler detection 280 // 281 // V8_CC_GNU - GCC, or clang in gcc mode 282 // V8_CC_INTEL - Intel C++ 283 // V8_CC_MINGW - Minimalist GNU for Windows 284 // V8_CC_MINGW32 - Minimalist GNU for Windows (mingw32) 285 // V8_CC_MINGW64 - Minimalist GNU for Windows (mingw-w64) 286 // V8_CC_MSVC - Microsoft Visual C/C++, or clang in cl.exe mode 287 // 288 // C++11 feature detection 289 // 290 // Compiler-specific feature detection 291 // 292 // V8_HAS_ATTRIBUTE_ALWAYS_INLINE - __attribute__((always_inline)) 293 // supported 294 // V8_HAS_ATTRIBUTE_CONSTINIT - __attribute__((require_constant_ 295 // initialization)) 296 // supported 297 // V8_HAS_ATTRIBUTE_NONNULL - __attribute__((nonnull)) supported 298 // V8_HAS_ATTRIBUTE_NOINLINE - __attribute__((noinline)) supported 299 // V8_HAS_ATTRIBUTE_UNUSED - __attribute__((unused)) supported 300 // V8_HAS_ATTRIBUTE_VISIBILITY - __attribute__((visibility)) supported 301 // V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT - __attribute__((warn_unused_result)) 302 // supported 303 // V8_HAS_CPP_ATTRIBUTE_NODISCARD - [[nodiscard]] supported 304 // V8_HAS_CPP_ATTRIBUTE_NO_UNIQUE_ADDRESS 305 // - [[no_unique_address]] supported 306 // V8_HAS_BUILTIN_BSWAP16 - __builtin_bswap16() supported 307 // V8_HAS_BUILTIN_BSWAP32 - __builtin_bswap32() supported 308 // V8_HAS_BUILTIN_BSWAP64 - __builtin_bswap64() supported 309 // V8_HAS_BUILTIN_CLZ - __builtin_clz() supported 310 // V8_HAS_BUILTIN_CTZ - __builtin_ctz() supported 311 // V8_HAS_BUILTIN_EXPECT - __builtin_expect() supported 312 // V8_HAS_BUILTIN_FRAME_ADDRESS - __builtin_frame_address() supported 313 // V8_HAS_BUILTIN_POPCOUNT - __builtin_popcount() supported 314 // V8_HAS_BUILTIN_ADD_OVERFLOW - __builtin_add_overflow() supported 315 // V8_HAS_BUILTIN_SUB_OVERFLOW - __builtin_sub_overflow() supported 316 // V8_HAS_BUILTIN_MUL_OVERFLOW - __builtin_mul_overflow() supported 317 // V8_HAS_BUILTIN_SADD_OVERFLOW - __builtin_sadd_overflow() supported 318 // V8_HAS_BUILTIN_SSUB_OVERFLOW - __builtin_ssub_overflow() supported 319 // V8_HAS_BUILTIN_UADD_OVERFLOW - __builtin_uadd_overflow() supported 320 // V8_HAS_BUILTIN_SMUL_OVERFLOW - __builtin_smul_overflow() supported 321 // V8_HAS_COMPUTED_GOTO - computed goto/labels as values 322 // supported 323 // V8_HAS_DECLSPEC_NOINLINE - __declspec(noinline) supported 324 // V8_HAS_DECLSPEC_SELECTANY - __declspec(selectany) supported 325 // V8_HAS___FORCEINLINE - __forceinline supported 326 // 327 // Note that testing for compilers and/or features must be done using #if 328 // not #ifdef. For example, to test for Intel C++ Compiler, use: 329 // #if V8_CC_INTEL 330 // ... 331 // #endif 332 333 #if defined(__has_cpp_attribute) 334 #define V8_HAS_CPP_ATTRIBUTE(FEATURE) __has_cpp_attribute(FEATURE) 335 #else 336 #define V8_HAS_CPP_ATTRIBUTE(FEATURE) 0 337 #endif 338 339 #if defined(__clang__) 340 341 #if defined(__GNUC__) // Clang in gcc mode. 342 # define V8_CC_GNU 1 343 #endif 344 345 # define V8_HAS_ATTRIBUTE_ALWAYS_INLINE (__has_attribute(always_inline)) 346 # define V8_HAS_ATTRIBUTE_CONSTINIT \ 347 (__has_attribute(require_constant_initialization)) 348 # define V8_HAS_ATTRIBUTE_CONST (__has_attribute(const)) 349 # define V8_HAS_ATTRIBUTE_NONNULL (__has_attribute(nonnull)) 350 # define V8_HAS_ATTRIBUTE_NOINLINE (__has_attribute(noinline)) 351 # define V8_HAS_ATTRIBUTE_UNUSED (__has_attribute(unused)) 352 // Support for the "preserve_most" attribute is limited: 353 // - 32-bit platforms do not implement it, 354 // - component builds fail because _dl_runtime_resolve clobbers registers, 355 // - we see crashes on arm64 on Windows (https://crbug.com/1409934), which can 356 // hopefully be fixed in the future. 357 // Additionally, the initial implementation in clang <= 16 overwrote the return 358 // register(s) in the epilogue of a preserve_most function, so we only use 359 // preserve_most in clang >= 17 (see https://reviews.llvm.org/D143425). 360 #if (defined(_M_X64) || defined(__x86_64__) /* x64 (everywhere) */ \ 361 || ((defined(__AARCH64EL__) || defined(_M_ARM64)) /* arm64, but ... */ \ 362 && !defined(_WIN32))) /* not on windows */ \ 363 && !defined(COMPONENT_BUILD) /* no component build */\ 364 && __clang_major__ >= 17 /* clang >= 17 */ 365 # define V8_HAS_ATTRIBUTE_PRESERVE_MOST (__has_attribute(preserve_most)) 366 #endif 367 # define V8_HAS_ATTRIBUTE_VISIBILITY (__has_attribute(visibility)) 368 # define V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT \ 369 (__has_attribute(warn_unused_result)) 370 371 # define V8_HAS_CPP_ATTRIBUTE_NODISCARD (V8_HAS_CPP_ATTRIBUTE(nodiscard)) 372 # define V8_HAS_CPP_ATTRIBUTE_NO_UNIQUE_ADDRESS \ 373 (V8_HAS_CPP_ATTRIBUTE(no_unique_address)) 374 375 # define V8_HAS_BUILTIN_ASSUME (__has_builtin(__builtin_assume)) 376 # define V8_HAS_BUILTIN_ASSUME_ALIGNED (__has_builtin(__builtin_assume_aligned)) 377 # define V8_HAS_BUILTIN_BSWAP16 (__has_builtin(__builtin_bswap16)) 378 # define V8_HAS_BUILTIN_BSWAP32 (__has_builtin(__builtin_bswap32)) 379 # define V8_HAS_BUILTIN_BSWAP64 (__has_builtin(__builtin_bswap64)) 380 # define V8_HAS_BUILTIN_CLZ (__has_builtin(__builtin_clz)) 381 # define V8_HAS_BUILTIN_CTZ (__has_builtin(__builtin_ctz)) 382 # define V8_HAS_BUILTIN_EXPECT (__has_builtin(__builtin_expect)) 383 # define V8_HAS_BUILTIN_FRAME_ADDRESS (__has_builtin(__builtin_frame_address)) 384 # define V8_HAS_BUILTIN_POPCOUNT (__has_builtin(__builtin_popcount)) 385 # define V8_HAS_BUILTIN_ADD_OVERFLOW (__has_builtin(__builtin_add_overflow)) 386 # define V8_HAS_BUILTIN_SUB_OVERFLOW (__has_builtin(__builtin_sub_overflow)) 387 # define V8_HAS_BUILTIN_MUL_OVERFLOW (__has_builtin(__builtin_mul_overflow)) 388 # define V8_HAS_BUILTIN_SADD_OVERFLOW (__has_builtin(__builtin_sadd_overflow)) 389 # define V8_HAS_BUILTIN_SSUB_OVERFLOW (__has_builtin(__builtin_ssub_overflow)) 390 # define V8_HAS_BUILTIN_UADD_OVERFLOW (__has_builtin(__builtin_uadd_overflow)) 391 # define V8_HAS_BUILTIN_SMUL_OVERFLOW (__has_builtin(__builtin_smul_overflow)) 392 # define V8_HAS_BUILTIN_UNREACHABLE (__has_builtin(__builtin_unreachable)) 393 394 // Clang has no __has_feature for computed gotos. 395 // GCC doc: https://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html 396 # define V8_HAS_COMPUTED_GOTO 1 397 398 #elif defined(__GNUC__) 399 400 # define V8_CC_GNU 1 401 # if defined(__INTEL_COMPILER) // Intel C++ also masquerades as GCC 3.2.0 402 # define V8_CC_INTEL 1 403 # endif 404 # if defined(__MINGW32__) 405 # define V8_CC_MINGW32 1 406 # endif 407 # if defined(__MINGW64__) 408 # define V8_CC_MINGW64 1 409 # endif 410 # define V8_CC_MINGW (V8_CC_MINGW32 || V8_CC_MINGW64) 411 412 // always_inline is available in gcc 4.0 but not very reliable until 4.4. 413 // Works around "sorry, unimplemented: inlining failed" build errors with 414 // older compilers. 415 # define V8_HAS_ATTRIBUTE_ALWAYS_INLINE 1 416 # define V8_HAS_ATTRIBUTE_NOINLINE 1 417 # define V8_HAS_ATTRIBUTE_UNUSED 1 418 # define V8_HAS_ATTRIBUTE_VISIBILITY 1 419 # define V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT (!V8_CC_INTEL) 420 421 // [[nodiscard]] does not work together with with 422 // __attribute__((visibility(""))) on GCC 7.4 which is why there is no define 423 // for V8_HAS_CPP_ATTRIBUTE_NODISCARD. See https://crbug.com/v8/11707. 424 425 # define V8_HAS_BUILTIN_ASSUME_ALIGNED 1 426 # define V8_HAS_BUILTIN_CLZ 1 427 # define V8_HAS_BUILTIN_CTZ 1 428 # define V8_HAS_BUILTIN_EXPECT 1 429 # define V8_HAS_BUILTIN_FRAME_ADDRESS 1 430 # define V8_HAS_BUILTIN_POPCOUNT 1 431 # define V8_HAS_BUILTIN_UNREACHABLE 1 432 433 // GCC doc: https://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html 434 #define V8_HAS_COMPUTED_GOTO 1 435 436 #endif 437 438 #if defined(_MSC_VER) 439 # define V8_CC_MSVC 1 440 441 # define V8_HAS_DECLSPEC_NOINLINE 1 442 # define V8_HAS_DECLSPEC_SELECTANY 1 443 444 # define V8_HAS___FORCEINLINE 1 445 446 #endif 447 448 449 // ----------------------------------------------------------------------------- 450 // Helper macros 451 452 // A macro used to make better inlining. Don't bother for debug builds. 453 // Use like: 454 // V8_INLINE int GetZero() { return 0; } 455 #if !defined(DEBUG) && V8_HAS_ATTRIBUTE_ALWAYS_INLINE 456 # define V8_INLINE inline __attribute__((always_inline)) 457 #elif !defined(DEBUG) && V8_HAS___FORCEINLINE 458 # define V8_INLINE __forceinline 459 #else 460 # define V8_INLINE inline 461 #endif 462 463 #ifdef DEBUG 464 // In debug mode, check assumptions instead of actually adding annotations. 465 # define V8_ASSUME(condition) DCHECK(condition) 466 #elif V8_HAS_BUILTIN_ASSUME 467 # define V8_ASSUME(condition) __builtin_assume(condition) 468 #elif V8_HAS_BUILTIN_UNREACHABLE 469 # define V8_ASSUME(condition) \ 470 do { if (!(condition)) __builtin_unreachable(); } while (false) 471 #else 472 # define V8_ASSUME(condition) 473 #endif 474 475 #if V8_HAS_BUILTIN_ASSUME_ALIGNED 476 # define V8_ASSUME_ALIGNED(ptr, alignment) \ 477 __builtin_assume_aligned((ptr), (alignment)) 478 #else 479 # define V8_ASSUME_ALIGNED(ptr, alignment) (ptr) 480 #endif 481 482 483 // A macro to mark functions whose values don't change (e.g. across calls) 484 // and thereby compiler is free to hoist and fold multiple calls together. 485 // Use like: 486 // V8_CONST int foo() { ... } 487 #if V8_HAS_ATTRIBUTE_CONST 488 # define V8_CONST __attribute__((const)) 489 #else 490 # define V8_CONST 491 #endif 492 493 // A macro to mark a declaration as requiring constant initialization. 494 // Use like: 495 // int* foo V8_CONSTINIT; 496 #if V8_HAS_ATTRIBUTE_CONSTINIT 497 # define V8_CONSTINIT __attribute__((require_constant_initialization)) 498 #else 499 # define V8_CONSTINIT 500 #endif 501 502 503 // A macro to mark specific arguments as non-null. 504 // Use like: 505 // int add(int* x, int y, int* z) V8_NONNULL(1, 3) { return *x + y + *z; } 506 #if V8_HAS_ATTRIBUTE_NONNULL 507 # define V8_NONNULL(...) __attribute__((nonnull(__VA_ARGS__))) 508 #else 509 # define V8_NONNULL(...) /* NOT SUPPORTED */ 510 #endif 511 512 513 // A macro used to tell the compiler to never inline a particular function. 514 // Use like: 515 // V8_NOINLINE int GetMinusOne() { return -1; } 516 #if V8_HAS_ATTRIBUTE_NOINLINE 517 # define V8_NOINLINE __attribute__((noinline)) 518 #elif V8_HAS_DECLSPEC_NOINLINE 519 # define V8_NOINLINE __declspec(noinline) 520 #else 521 # define V8_NOINLINE /* NOT SUPPORTED */ 522 #endif 523 524 525 // A macro used to change the calling conventions to preserve all registers (no 526 // caller-saved registers). Use this for cold functions called from hot 527 // functions. 528 // Note: The attribute is considered experimental, so apply with care. Also, 529 // "preserve_most" is currently not handling the return value correctly, so only 530 // use it for functions returning void (see https://reviews.llvm.org/D141020). 531 // Use like: 532 // V8_NOINLINE V8_PRESERVE_MOST void UnlikelyMethod(); 533 #if V8_HAS_ATTRIBUTE_PRESERVE_MOST 534 # define V8_PRESERVE_MOST __attribute__((preserve_most)) 535 #else 536 # define V8_PRESERVE_MOST /* NOT SUPPORTED */ 537 #endif 538 539 540 // A macro (V8_DEPRECATED) to mark classes or functions as deprecated. 541 #if defined(V8_DEPRECATION_WARNINGS) 542 # define V8_DEPRECATED(message) [[deprecated(message)]] 543 #else 544 # define V8_DEPRECATED(message) 545 #endif 546 547 548 // A macro (V8_DEPRECATE_SOON) to make it easier to see what will be deprecated. 549 #if defined(V8_IMMINENT_DEPRECATION_WARNINGS) 550 # define V8_DEPRECATE_SOON(message) [[deprecated(message)]] 551 #else 552 # define V8_DEPRECATE_SOON(message) 553 #endif 554 555 556 #if defined(V8_IMMINENT_DEPRECATION_WARNINGS) || \ 557 defined(V8_DEPRECATION_WARNINGS) 558 #if defined(V8_CC_MSVC) 559 # define START_ALLOW_USE_DEPRECATED() \ 560 __pragma(warning(push)) \ 561 __pragma(warning(disable : 4996)) 562 # define END_ALLOW_USE_DEPRECATED() __pragma(warning(pop)) 563 #else // !defined(V8_CC_MSVC) 564 # define START_ALLOW_USE_DEPRECATED() \ 565 _Pragma("GCC diagnostic push") \ 566 _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") 567 #define END_ALLOW_USE_DEPRECATED() _Pragma("GCC diagnostic pop") 568 #endif // !defined(V8_CC_MSVC) 569 #else // !(defined(V8_IMMINENT_DEPRECATION_WARNINGS) || 570 // defined(V8_DEPRECATION_WARNINGS)) 571 #define START_ALLOW_USE_DEPRECATED() 572 #define END_ALLOW_USE_DEPRECATED() 573 #endif // !(defined(V8_IMMINENT_DEPRECATION_WARNINGS) || 574 // defined(V8_DEPRECATION_WARNINGS)) 575 #define ALLOW_COPY_AND_MOVE_WITH_DEPRECATED_FIELDS(ClassName) \ 576 START_ALLOW_USE_DEPRECATED() \ 577 ClassName(const ClassName&) = default; \ 578 ClassName(ClassName&&) = default; \ 579 ClassName& operator=(const ClassName&) = default; \ 580 ClassName& operator=(ClassName&&) = default; \ 581 END_ALLOW_USE_DEPRECATED() 582 583 584 #if defined(__GNUC__) && !defined(__clang__) && (__GNUC__ < 6) 585 # define V8_ENUM_DEPRECATED(message) 586 # define V8_ENUM_DEPRECATE_SOON(message) 587 #else 588 # define V8_ENUM_DEPRECATED(message) V8_DEPRECATED(message) 589 # define V8_ENUM_DEPRECATE_SOON(message) V8_DEPRECATE_SOON(message) 590 #endif 591 592 593 // A macro to provide the compiler with branch prediction information. 594 #if V8_HAS_BUILTIN_EXPECT 595 # define V8_UNLIKELY(condition) (__builtin_expect(!!(condition), 0)) 596 # define V8_LIKELY(condition) (__builtin_expect(!!(condition), 1)) 597 #else 598 # define V8_UNLIKELY(condition) (condition) 599 # define V8_LIKELY(condition) (condition) 600 #endif 601 602 603 // Annotate a function indicating the caller must examine the return value. 604 // Use like: 605 // int foo() V8_WARN_UNUSED_RESULT; 606 #if V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT 607 #define V8_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) 608 #else 609 #define V8_WARN_UNUSED_RESULT /* NOT SUPPORTED */ 610 #endif 611 612 613 // Annotate a class or constructor indicating the caller must assign the 614 // constructed instances. 615 // Apply to the whole class like: 616 // class V8_NODISCARD Foo() { ... }; 617 // or apply to just one constructor like: 618 // V8_NODISCARD Foo() { ... }; 619 // [[nodiscard]] comes in C++17 but supported in clang with -std >= c++11. 620 #if V8_HAS_CPP_ATTRIBUTE_NODISCARD 621 #define V8_NODISCARD [[nodiscard]] 622 #else 623 #define V8_NODISCARD /* NOT SUPPORTED */ 624 #endif 625 626 // The no_unique_address attribute allows tail padding in a non-static data 627 // member to overlap other members of the enclosing class (and in the special 628 // case when the type is empty, permits it to fully overlap other members). The 629 // field is laid out as if a base class were encountered at the corresponding 630 // point within the class (except that it does not share a vptr with the 631 // enclosing object). 632 // 633 // Apply to a data member like: 634 // 635 // class Foo { 636 // V8_NO_UNIQUE_ADDRESS Bar bar_; 637 // }; 638 // 639 // [[no_unique_address]] comes in C++20 but supported in clang with 640 // -std >= c++11. 641 #if V8_HAS_CPP_ATTRIBUTE_NO_UNIQUE_ADDRESS 642 #define V8_NO_UNIQUE_ADDRESS [[no_unique_address]] 643 #else 644 #define V8_NO_UNIQUE_ADDRESS /* NOT SUPPORTED */ 645 #endif 646 647 // Marks a type as being eligible for the "trivial" ABI despite having a 648 // non-trivial destructor or copy/move constructor. Such types can be relocated 649 // after construction by simply copying their memory, which makes them eligible 650 // to be passed in registers. The canonical example is std::unique_ptr. 651 // 652 // Use with caution; this has some subtle effects on constructor/destructor 653 // ordering and will be very incorrect if the type relies on its address 654 // remaining constant. When used as a function argument (by value), the value 655 // may be constructed in the caller's stack frame, passed in a register, and 656 // then used and destructed in the callee's stack frame. A similar thing can 657 // occur when values are returned. 658 // 659 // TRIVIAL_ABI is not needed for types which have a trivial destructor and 660 // copy/move constructors, since those are automatically trivial by the ABI 661 // spec. 662 // 663 // It is also not likely to be effective on types too large to be passed in one 664 // or two registers on typical target ABIs. 665 // 666 // See also: 667 // https://clang.llvm.org/docs/AttributeReference.html#trivial-abi 668 // https://libcxx.llvm.org/docs/DesignDocs/UniquePtrTrivialAbi.html 669 #if defined(__clang__) && defined(__has_attribute) 670 #if __has_attribute(trivial_abi) 671 #define V8_TRIVIAL_ABI [[clang::trivial_abi]] 672 #endif // __has_attribute(trivial_abi) 673 #endif // defined(__clang__) && defined(__has_attribute) 674 #if !defined(V8_TRIVIAL_ABI) 675 #define V8_TRIVIAL_ABI 676 #endif //!defined(V8_TRIVIAL_ABI) 677 678 // Helper macro to define no_sanitize attributes only with clang. 679 #if defined(__clang__) && defined(__has_attribute) 680 #if __has_attribute(no_sanitize) 681 #define V8_CLANG_NO_SANITIZE(what) __attribute__((no_sanitize(what))) 682 #endif 683 #endif 684 #if !defined(V8_CLANG_NO_SANITIZE) 685 #define V8_CLANG_NO_SANITIZE(what) 686 #endif 687 688 #if defined(BUILDING_V8_SHARED) && defined(USING_V8_SHARED) 689 #error Inconsistent build configuration: To build the V8 shared library \ 690 set BUILDING_V8_SHARED, to include its headers for linking against the \ 691 V8 shared library set USING_V8_SHARED. 692 #endif 693 694 #ifdef V8_OS_WIN 695 696 // Setup for Windows DLL export/import. When building the V8 DLL the 697 // BUILDING_V8_SHARED needs to be defined. When building a program which uses 698 // the V8 DLL USING_V8_SHARED needs to be defined. When either building the V8 699 // static library or building a program which uses the V8 static library neither 700 // BUILDING_V8_SHARED nor USING_V8_SHARED should be defined. 701 #ifdef BUILDING_V8_SHARED 702 # define V8_EXPORT __declspec(dllexport) 703 #elif USING_V8_SHARED 704 # define V8_EXPORT __declspec(dllimport) 705 #else 706 # define V8_EXPORT 707 #endif // BUILDING_V8_SHARED 708 709 #else // V8_OS_WIN 710 711 // Setup for Linux shared library export. 712 #if V8_HAS_ATTRIBUTE_VISIBILITY 713 # ifdef BUILDING_V8_SHARED 714 # define V8_EXPORT __attribute__ ((visibility("default"))) 715 # else 716 # define V8_EXPORT 717 # endif 718 #else 719 # define V8_EXPORT 720 #endif 721 722 #endif // V8_OS_WIN 723 724 // clang-format on 725 726 // Processor architecture detection. For more info on what's defined, see: 727 // http://msdn.microsoft.com/en-us/library/b0084kay.aspx 728 // http://www.agner.org/optimize/calling_conventions.pdf 729 // or with gcc, run: "echo | gcc -E -dM -" 730 // The V8_HOST_ARCH_* macros correspond to the architecture on which V8, as a 731 // virtual machine and compiler, runs. Don't confuse this with the architecture 732 // on which V8 is built. 733 #if defined(_M_X64) || defined(__x86_64__) 734 #define V8_HOST_ARCH_X64 1 735 #if defined(__x86_64__) && __SIZEOF_POINTER__ == 4 // Check for x32. 736 #define V8_HOST_ARCH_32_BIT 1 737 #else 738 #define V8_HOST_ARCH_64_BIT 1 739 #endif 740 #elif defined(_M_IX86) || defined(__i386__) 741 #define V8_HOST_ARCH_IA32 1 742 #define V8_HOST_ARCH_32_BIT 1 743 #elif defined(__AARCH64EL__) || defined(_M_ARM64) 744 #define V8_HOST_ARCH_ARM64 1 745 #define V8_HOST_ARCH_64_BIT 1 746 #elif defined(__ARMEL__) 747 #define V8_HOST_ARCH_ARM 1 748 #define V8_HOST_ARCH_32_BIT 1 749 #elif defined(__mips64) 750 #define V8_HOST_ARCH_MIPS64 1 751 #define V8_HOST_ARCH_64_BIT 1 752 #elif defined(__loongarch64) 753 #define V8_HOST_ARCH_LOONG64 1 754 #define V8_HOST_ARCH_64_BIT 1 755 #elif defined(__PPC64__) || defined(_ARCH_PPC64) 756 #define V8_HOST_ARCH_PPC64 1 757 #define V8_HOST_ARCH_64_BIT 1 758 #elif defined(__PPC__) || defined(_ARCH_PPC) 759 #define V8_HOST_ARCH_PPC 1 760 #define V8_HOST_ARCH_32_BIT 1 761 #elif defined(__s390__) || defined(__s390x__) 762 #define V8_HOST_ARCH_S390 1 763 #if defined(__s390x__) 764 #define V8_HOST_ARCH_64_BIT 1 765 #else 766 #define V8_HOST_ARCH_32_BIT 1 767 #endif 768 #elif defined(__riscv) || defined(__riscv__) 769 #if __riscv_xlen == 64 770 #define V8_HOST_ARCH_RISCV64 1 771 #define V8_HOST_ARCH_64_BIT 1 772 #elif __riscv_xlen == 32 773 #define V8_HOST_ARCH_RISCV32 1 774 #define V8_HOST_ARCH_32_BIT 1 775 #else 776 #error "Cannot detect Riscv's bitwidth" 777 #endif 778 #else 779 #error "Host architecture was not detected as supported by v8" 780 #endif 781 782 // Target architecture detection. This corresponds to the architecture for which 783 // V8's JIT will generate code (the last stage of the canadian cross-compiler). 784 // The macros may be set externally. If not, detect in the same way as the host 785 // architecture, that is, target the native environment as presented by the 786 // compiler. 787 #if !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_IA32 && !V8_TARGET_ARCH_ARM && \ 788 !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_MIPS64 && !V8_TARGET_ARCH_PPC && \ 789 !V8_TARGET_ARCH_PPC64 && !V8_TARGET_ARCH_S390 && \ 790 !V8_TARGET_ARCH_RISCV64 && !V8_TARGET_ARCH_LOONG64 && \ 791 !V8_TARGET_ARCH_RISCV32 792 #if defined(_M_X64) || defined(__x86_64__) 793 #define V8_TARGET_ARCH_X64 1 794 #elif defined(_M_IX86) || defined(__i386__) 795 #define V8_TARGET_ARCH_IA32 1 796 #elif defined(__AARCH64EL__) || defined(_M_ARM64) 797 #define V8_TARGET_ARCH_ARM64 1 798 #elif defined(__ARMEL__) 799 #define V8_TARGET_ARCH_ARM 1 800 #elif defined(__mips64) 801 #define V8_TARGET_ARCH_MIPS64 1 802 #elif defined(__loongarch64) 803 #define V8_TARGET_ARCH_LOONG64 1 804 #elif defined(_ARCH_PPC64) 805 #define V8_TARGET_ARCH_PPC64 1 806 #elif defined(_ARCH_PPC) 807 #define V8_TARGET_ARCH_PPC 1 808 #elif defined(__s390__) 809 #define V8_TARGET_ARCH_S390 1 810 #if defined(__s390x__) 811 #define V8_TARGET_ARCH_S390X 1 812 #endif 813 #elif defined(__riscv) || defined(__riscv__) 814 #if __riscv_xlen == 64 815 #define V8_TARGET_ARCH_RISCV64 1 816 #elif __riscv_xlen == 32 817 #define V8_TARGET_ARCH_RISCV32 1 818 #endif 819 #else 820 #error Target architecture was not detected as supported by v8 821 #endif 822 #endif 823 824 // Determine architecture pointer size. 825 #if V8_TARGET_ARCH_IA32 826 #define V8_TARGET_ARCH_32_BIT 1 827 #elif V8_TARGET_ARCH_X64 828 #if !V8_TARGET_ARCH_32_BIT && !V8_TARGET_ARCH_64_BIT 829 #if defined(__x86_64__) && __SIZEOF_POINTER__ == 4 // Check for x32. 830 #define V8_TARGET_ARCH_32_BIT 1 831 #else 832 #define V8_TARGET_ARCH_64_BIT 1 833 #endif 834 #endif 835 #elif V8_TARGET_ARCH_ARM 836 #define V8_TARGET_ARCH_32_BIT 1 837 #elif V8_TARGET_ARCH_ARM64 838 #define V8_TARGET_ARCH_64_BIT 1 839 #elif V8_TARGET_ARCH_MIPS 840 #define V8_TARGET_ARCH_32_BIT 1 841 #elif V8_TARGET_ARCH_MIPS64 842 #define V8_TARGET_ARCH_64_BIT 1 843 #elif V8_TARGET_ARCH_LOONG64 844 #define V8_TARGET_ARCH_64_BIT 1 845 #elif V8_TARGET_ARCH_PPC 846 #define V8_TARGET_ARCH_32_BIT 1 847 #elif V8_TARGET_ARCH_PPC64 848 #define V8_TARGET_ARCH_64_BIT 1 849 #elif V8_TARGET_ARCH_S390 850 #if V8_TARGET_ARCH_S390X 851 #define V8_TARGET_ARCH_64_BIT 1 852 #else 853 #define V8_TARGET_ARCH_32_BIT 1 854 #endif 855 #elif V8_TARGET_ARCH_RISCV64 856 #define V8_TARGET_ARCH_64_BIT 1 857 #elif V8_TARGET_ARCH_RISCV32 858 #define V8_TARGET_ARCH_32_BIT 1 859 #else 860 #error Unknown target architecture pointer size 861 #endif 862 863 // Check for supported combinations of host and target architectures. 864 #if V8_TARGET_ARCH_IA32 && !V8_HOST_ARCH_IA32 865 #error Target architecture ia32 is only supported on ia32 host 866 #endif 867 #if (V8_TARGET_ARCH_X64 && V8_TARGET_ARCH_64_BIT && \ 868 !((V8_HOST_ARCH_X64 || V8_HOST_ARCH_ARM64) && V8_HOST_ARCH_64_BIT)) 869 #error Target architecture x64 is only supported on x64 and arm64 host 870 #endif 871 #if (V8_TARGET_ARCH_X64 && V8_TARGET_ARCH_32_BIT && \ 872 !(V8_HOST_ARCH_X64 && V8_HOST_ARCH_32_BIT)) 873 #error Target architecture x32 is only supported on x64 host with x32 support 874 #endif 875 #if (V8_TARGET_ARCH_ARM && !(V8_HOST_ARCH_IA32 || V8_HOST_ARCH_ARM)) 876 #error Target architecture arm is only supported on arm and ia32 host 877 #endif 878 #if (V8_TARGET_ARCH_ARM64 && !(V8_HOST_ARCH_X64 || V8_HOST_ARCH_ARM64)) 879 #error Target architecture arm64 is only supported on arm64 and x64 host 880 #endif 881 #if (V8_TARGET_ARCH_MIPS64 && !(V8_HOST_ARCH_X64 || V8_HOST_ARCH_MIPS64)) 882 #error Target architecture mips64 is only supported on mips64 and x64 host 883 #endif 884 #if (V8_TARGET_ARCH_RISCV64 && !(V8_HOST_ARCH_X64 || V8_HOST_ARCH_RISCV64)) 885 #error Target architecture riscv64 is only supported on riscv64 and x64 host 886 #endif 887 #if (V8_TARGET_ARCH_RISCV32 && !(V8_HOST_ARCH_IA32 || V8_HOST_ARCH_RISCV32)) 888 #error Target architecture riscv32 is only supported on riscv32 and ia32 host 889 #endif 890 #if (V8_TARGET_ARCH_LOONG64 && !(V8_HOST_ARCH_X64 || V8_HOST_ARCH_LOONG64)) 891 #error Target architecture loong64 is only supported on loong64 and x64 host 892 #endif 893 894 // Determine architecture endianness. 895 #if V8_TARGET_ARCH_IA32 896 #define V8_TARGET_LITTLE_ENDIAN 1 897 #elif V8_TARGET_ARCH_X64 898 #define V8_TARGET_LITTLE_ENDIAN 1 899 #elif V8_TARGET_ARCH_ARM 900 #define V8_TARGET_LITTLE_ENDIAN 1 901 #elif V8_TARGET_ARCH_ARM64 902 #define V8_TARGET_LITTLE_ENDIAN 1 903 #elif V8_TARGET_ARCH_LOONG64 904 #define V8_TARGET_LITTLE_ENDIAN 1 905 #elif V8_TARGET_ARCH_MIPS64 906 #if defined(__MIPSEB__) || defined(V8_TARGET_ARCH_MIPS64_BE) 907 #define V8_TARGET_BIG_ENDIAN 1 908 #else 909 #define V8_TARGET_LITTLE_ENDIAN 1 910 #endif 911 #elif defined(__BIG_ENDIAN__) // FOR PPCGR on AIX 912 #define V8_TARGET_BIG_ENDIAN 1 913 #elif V8_TARGET_ARCH_PPC_LE 914 #define V8_TARGET_LITTLE_ENDIAN 1 915 #elif V8_TARGET_ARCH_PPC_BE 916 #define V8_TARGET_BIG_ENDIAN 1 917 #elif V8_TARGET_ARCH_S390 918 #if V8_TARGET_ARCH_S390_LE_SIM 919 #define V8_TARGET_LITTLE_ENDIAN 1 920 #else 921 #define V8_TARGET_BIG_ENDIAN 1 922 #endif 923 #elif V8_TARGET_ARCH_RISCV32 || V8_TARGET_ARCH_RISCV64 924 #define V8_TARGET_LITTLE_ENDIAN 1 925 #elif defined(__BYTE_ORDER__) 926 #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ 927 #define V8_TARGET_BIG_ENDIAN 1 928 #else 929 #define V8_TARGET_LITTLE_ENDIAN 1 930 #endif 931 #else 932 #error Unknown target architecture endianness 933 #endif 934 935 #undef V8_HAS_CPP_ATTRIBUTE 936 937 #if !defined(V8_STATIC_ROOTS) 938 #define V8_STATIC_ROOTS_BOOL false 939 #else 940 #define V8_STATIC_ROOTS_BOOL true 941 #endif 942 943 #endif // V8CONFIG_H_ 944