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