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