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