v8 11.3.244 (node 20.3.0)
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// 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
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_