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 \ 11path. 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 \ 690set BUILDING_V8_SHARED, to include its headers for linking against the \ 691V8 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