5#ifndef V8_BASE_MACROS_H_
6#define V8_BASE_MACROS_H_
21#define CONCAT_(a, ...) a##__VA_ARGS__
22#define CONCAT(a, ...) CONCAT_(a, __VA_ARGS__)
24#define UNIQUE_IDENTIFIER(base) CONCAT(base, __COUNTER__)
28#define COUNT_MACRO_ARGS(...) \
29 EXPAND(COUNT_MACRO_ARGS_IMPL(__VA_ARGS__, 8, 7, 6, 5, 4, 3, 2, 1, 0))
30#define COUNT_MACRO_ARGS_IMPL(_8, _7, _6, _5, _4, _3, _2, _1, N, ...) N
33#define GET_NTH_ARG(N, ...) CONCAT(GET_NTH_ARG_IMPL_, N)(__VA_ARGS__)
34#define GET_NTH_ARG_IMPL_0(_0, ...) _0
35#define GET_NTH_ARG_IMPL_1(_0, _1, ...) _1
36#define GET_NTH_ARG_IMPL_2(_0, _1, _2, ...) _2
37#define GET_NTH_ARG_IMPL_3(_0, _1, _2, _3, ...) _3
38#define GET_NTH_ARG_IMPL_4(_0, _1, _2, _3, _4, ...) _4
39#define GET_NTH_ARG_IMPL_5(_0, _1, _2, _3, _4, _5, ...) _5
40#define GET_NTH_ARG_IMPL_6(_0, _1, _2, _3, _4, _5, _6, ...) _6
41#define GET_NTH_ARG_IMPL_7(_0, _1, _2, _3, _4, _5, _6, _7, ...) _7
53#define UNPAREN(X) CONCAT(DROP_, UNPAREN_ X)
54#define UNPAREN_(...) UNPAREN_ __VA_ARGS__
57#define OFFSET_OF(type, field) offsetof(type, field)
61#define LITERAL_COMMA ,
67#define arraysize(array) (sizeof(ArraySizeHelper(array)))
72template <
typename T,
size_t N>
79template <
typename T,
size_t N>
94template <
class Dest,
class Source>
96 static_assert(!std::is_pointer_v<Source>,
97 "bit_cast must not be used on pointer types");
98 static_assert(!std::is_pointer_v<Dest>,
99 "bit_cast must not be used on pointer types");
100 static_assert(!std::is_reference_v<Dest>,
101 "bit_cast must not be used on reference types");
103 sizeof(Dest) ==
sizeof(Source),
104 "bit_cast requires source and destination types to be the same size");
105 static_assert(std::is_trivially_copyable_v<Source>,
106 "bit_cast requires the source type to be trivially copyable");
108 std::is_trivially_copyable_v<Dest>,
109 "bit_cast requires the destination type to be trivially copyable");
111#if V8_HAS_BUILTIN_BIT_CAST
112 return __builtin_bit_cast(Dest, source);
115 memcpy(&dest, &source,
sizeof(dest));
125#define DISALLOW_ASSIGN(TypeName) TypeName& operator=(const TypeName&) = delete
130#define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \
131 TypeName() = delete; \
132 TypeName(const TypeName&) = delete; \
133 DISALLOW_ASSIGN(TypeName)
137#define MOVE_ONLY_WITH_DEFAULT_CONSTRUCTORS(TypeName) \
138 TypeName() = default; \
139 MOVE_ONLY_NO_DEFAULT_CONSTRUCTOR(TypeName)
143#define MOVE_ONLY_NO_DEFAULT_CONSTRUCTOR(TypeName) \
144 TypeName(TypeName&&) V8_NOEXCEPT = default; \
145 TypeName& operator=(TypeName&&) V8_NOEXCEPT = default; \
146 TypeName(const TypeName&) = delete; \
147 DISALLOW_ASSIGN(TypeName)
155#define DISALLOW_NEW_AND_DELETE() \
156 void* operator new(size_t) { v8::base::OS::Abort(); } \
157 void* operator new[](size_t) { v8::base::OS::Abort(); } \
158 void operator delete(void*, size_t) { v8::base::OS::Abort(); } \
159 void operator delete[](void*, size_t) { v8::base::OS::Abort(); }
162#if defined(__has_feature)
163#if __has_feature(address_sanitizer)
164#define V8_USE_ADDRESS_SANITIZER 1
169#if defined(__has_feature)
170#if __has_feature(hwaddress_sanitizer)
171#define V8_USE_HWADDRESS_SANITIZER 1
176#if defined(__has_feature)
177#if __has_feature(memory_sanitizer)
178#define V8_USE_MEMORY_SANITIZER 1
183#if defined(__has_feature)
184#if __has_feature(undefined_behavior_sanitizer)
185#define V8_USE_UNDEFINED_BEHAVIOR_SANITIZER 1
190#if defined(__has_feature)
191#if __has_feature(safe_stack)
192#define V8_USE_SAFE_STACK 1
197#define DISABLE_CFI_PERF V8_CLANG_NO_SANITIZE("cfi")
204#define DISABLE_CFI_ICALL \
205 V8_CLANG_NO_SANITIZE("cfi-icall") \
206 V8_CLANG_NO_SANITIZE("function") \
207 __declspec(guard(nocf))
209#define DISABLE_CFI_ICALL \
210 V8_CLANG_NO_SANITIZE("cfi-icall") \
211 V8_CLANG_NO_SANITIZE("function")
216#if defined(V8_CC_GNU)
217#define V8_PRETTY_FUNCTION_VALUE_OR(ELSE) __PRETTY_FUNCTION__
218#elif defined(V8_CC_MSVC)
219#define V8_PRETTY_FUNCTION_VALUE_OR(ELSE) __FUNCSIG__
221#define V8_PRETTY_FUNCTION_VALUE_OR(ELSE) ELSE
233#if V8_CC_MSVC || (__GNUC__ == 12 && __GNUC_MINOR__ <= 2)
246 static constexpr bool value =
248 (std::is_trivially_copy_constructible<T>::value ||
249 !std::is_copy_constructible<T>::value) &&
251 (std::is_trivially_copy_assignable<T>::value ||
252 !std::is_copy_assignable<T>::value) &&
254 (std::is_trivially_move_constructible<T>::value ||
255 !std::is_move_constructible<T>::value) &&
257 (std::is_trivially_move_assignable<T>::value ||
258 !std::is_move_assignable<T>::value) &&
262 std::is_trivially_destructible<T>::value;
264 static constexpr bool value = std::is_trivially_copyable<T>::value;
267#define ASSERT_TRIVIALLY_COPYABLE(T) \
268 static_assert(::v8::base::is_trivially_copyable<T>::value, \
269 #T " should be trivially copyable")
270#define ASSERT_NOT_TRIVIALLY_COPYABLE(T) \
271 static_assert(!::v8::base::is_trivially_copyable<T>::value, \
272 #T " should not be trivially copyable")
279#define ASSERT_TRIVIALLY_DESTRUCTIBLE(T) \
280 static_assert(::v8::base::is_trivially_destructible<T>::value, \
281 #T " should be trivially destructible")
282#define ASSERT_NOT_TRIVIALLY_DESTRUCTIBLE(T) \
283 static_assert(!::v8::base::is_trivially_destructible<T>::value, \
284 #T " should not be trivially destructible")
290 template <
typename T>
295 ::v8::base::Use unused_tmp_array_for_use_macro[]{__VA_ARGS__}; \
296 (void)unused_tmp_array_for_use_macro; \
314# if V8_HOST_ARCH_64_BIT
315# define V8_PTR_PREFIX "ll"
317# define V8_PTR_PREFIX ""
320# define V8_PTR_PREFIX "I64"
321#elif V8_HOST_ARCH_64_BIT
322# define V8_PTR_PREFIX "l"
325#define V8_PTR_PREFIX "l"
327# define V8_PTR_PREFIX ""
331#define V8PRIxPTR V8_PTR_PREFIX "x"
332#define V8PRIdPTR V8_PTR_PREFIX "d"
333#define V8PRIuPTR V8_PTR_PREFIX "u"
335#if V8_TARGET_ARCH_64_BIT
336#define V8_PTR_HEX_DIGITS 12
337#define V8PRIxPTR_FMT "0x%012" V8PRIxPTR
339#define V8_PTR_HEX_DIGITS 8
340#define V8PRIxPTR_FMT "0x%08" V8PRIxPTR
345#define V8PRIxPTRDIFF "Ix"
346#define V8PRIdPTRDIFF "Id"
347#define V8PRIuPTRDIFF "Iu"
349#define V8PRIxPTRDIFF "tx"
350#define V8PRIdPTRDIFF "td"
351#define V8PRIuPTRDIFF "tu"
357#define V8PRIxPTR "lx"
359#define V8PRIdPTR "ld"
361#define V8PRIuPTR "lxu"
366 return (uint64_t{high} << 32) + low;
372 static_assert(std::is_integral<T>::value);
375 return x &
static_cast<T
>(-
m);
377template <
intptr_t m,
typename T>
379 static_assert(std::is_integral<T>::value);
381 static_assert(
m != 0 && ((
m & (
m - 1)) == 0));
382 return x &
static_cast<T
>(-
m);
388 static_assert(std::is_integral<T>::value);
390 DCHECK_GE(std::numeric_limits<T>::max() -
x,
m - 1);
394template <
intptr_t m,
typename T>
396 static_assert(std::is_integral<T>::value);
398 DCHECK_GE(std::numeric_limits<T>::max() -
x,
m - 1);
402template <
typename T,
typename U>
404 return (value & (alignment - 1)) == 0;
408 return reinterpret_cast<void*
>(
409 RoundDown(
reinterpret_cast<uintptr_t
>(address), alignment));
413 return reinterpret_cast<void*
>(
414 RoundUp(
reinterpret_cast<uintptr_t
>(address), alignment));
419template <
typename int_t,
typename float_t,
typename biggest_
int_t =
int64_t>
421 static_assert(
sizeof(int_t) <
sizeof(biggest_int_t),
422 "int_t can't be bounds checked by the compiler");
423 constexpr float_t kLowerBound =
424 static_cast<float_t
>(std::numeric_limits<int_t>::min()) - 1;
425 constexpr float_t kUpperBound =
426 static_cast<float_t
>(std::numeric_limits<int_t>::max()) + 1;
427 constexpr bool kLowerBoundIsMin =
428 static_cast<biggest_int_t
>(kLowerBound) ==
429 static_cast<biggest_int_t
>(std::numeric_limits<int_t>::min());
430 constexpr bool kUpperBoundIsMax =
431 static_cast<biggest_int_t
>(kUpperBound) ==
432 static_cast<biggest_int_t
>(std::numeric_limits<int_t>::max());
434 USE(kLowerBoundIsMin);
435 USE(kUpperBoundIsMax);
436 return (kLowerBoundIsMin ? (kLowerBound <= v) : (kLowerBound < v)) &&
437 (kUpperBoundIsMax ? (v <= kUpperBound) : (v < kUpperBound));
443#define V8_EXPORT_ENUM
444#ifdef BUILDING_V8_SHARED_PRIVATE
445#define V8_EXPORT_PRIVATE __declspec(dllexport)
446#elif USING_V8_SHARED_PRIVATE
447#define V8_EXPORT_PRIVATE __declspec(dllimport)
449#define V8_EXPORT_PRIVATE
455#if V8_HAS_ATTRIBUTE_VISIBILITY && \
456 (defined(BUILDING_V8_SHARED_PRIVATE) || USING_V8_SHARED_PRIVATE)
457#define V8_EXPORT_PRIVATE __attribute__((visibility("default")))
458#define V8_EXPORT_ENUM V8_EXPORT_PRIVATE
460#define V8_EXPORT_PRIVATE
461#define V8_EXPORT_ENUM
468#if V8_ENABLE_WEBASSEMBLY
470#define IF_WASM(V, ...) EXPAND(V(__VA_ARGS__))
472#define IF_WASM(V, ...)
475#ifdef V8_ENABLE_DRUMBRAKE
476#define IF_WASM_DRUMBRAKE(V, ...) EXPAND(V(__VA_ARGS__))
478#define IF_WASM_DRUMBRAKE(V, ...)
481#if defined(V8_ENABLE_DRUMBRAKE) && !defined(V8_DRUMBRAKE_BOUNDS_CHECKS)
482#define IF_WASM_DRUMBRAKE_INSTR_HANDLER(V, ...) EXPAND(V(__VA_ARGS__))
484#define IF_WASM_DRUMBRAKE_INSTR_HANDLER(V, ...)
491#define IF_TSAN(V, ...) EXPAND(V(__VA_ARGS__))
493#define IF_TSAN(V, ...)
498#ifdef V8_INTL_SUPPORT
500#define IF_INTL(V, ...) EXPAND(V(__VA_ARGS__))
502#define IF_INTL(V, ...)
507#ifdef V8_ENABLE_CET_SHADOW_STACK
509#define IF_SHADOW_STACK(V, ...) EXPAND(V(__VA_ARGS__))
511#define IF_SHADOW_STACK(V, ...)
516#if V8_TARGET_ARCH_64_BIT
518#define IF_TARGET_ARCH_64_BIT(V, ...) EXPAND(V(__VA_ARGS__))
520#define IF_TARGET_ARCH_64_BIT(V, ...)
526#ifdef V8_WASM_RANDOM_FUZZERS
528#define IF_V8_WASM_RANDOM_FUZZERS(V, ...) EXPAND(V(__VA_ARGS__))
529#define IF_NO_V8_WASM_RANDOM_FUZZERS(V, ...)
531#define IF_V8_WASM_RANDOM_FUZZERS(V, ...)
532#define IF_NO_V8_WASM_RANDOM_FUZZERS(V, ...) EXPAND(V(__VA_ARGS__))
537#define FRIEND_TEST(test_case_name, test_name)
V8_INLINE Dest bit_cast(Source const &source)
#define DCHECK_GE(v1, v2)
#define DCHECK(condition)
char(& ArraySizeHelper(T(&array)[N]))[N]
void * RoundUpAddress(void *address, size_t alignment)
V8_INLINE A implicit_cast(A x)
constexpr T RoundUp(T x, intptr_t m)
void * AlignedAddress(void *address, size_t alignment)
constexpr T RoundDown(T x, intptr_t m)
constexpr bool IsAligned(T value, U alignment)
uint64_t make_uint64(uint32_t high, uint32_t low)
bool is_inbounds(float_t v)