v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
macros.h
Go to the documentation of this file.
1// Copyright 2014 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 V8_BASE_MACROS_H_
6#define V8_BASE_MACROS_H_
7
8#include <limits>
9#include <type_traits>
10
11#include "include/v8config.h"
13#include "src/base/logging.h"
14
15// No-op macro which is used to work around MSVC's funky VA_ARGS support.
16#define EXPAND(X) X
17
18// This macro does nothing. That's all.
19#define NOTHING(...)
20
21#define CONCAT_(a, ...) a##__VA_ARGS__
22#define CONCAT(a, ...) CONCAT_(a, __VA_ARGS__)
23// Creates an unique identifier. Useful for scopes to avoid shadowing names.
24#define UNIQUE_IDENTIFIER(base) CONCAT(base, __COUNTER__)
25
26// COUNT_MACRO_ARGS(...) returns the number of arguments passed. Currently, up
27// to 8 arguments are supported.
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
31// GET_NTH_ARG(N, ...) returns the Nth argument in the list of arguments
32// following. Currently, up to N=8 is supported.
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
42
43// UNPAREN(x) removes a layer of nested parentheses on x, if any. This means
44// that both UNPAREN(x) and UNPAREN((x)) expand to x. This is helpful for macros
45// that want to support multi argument templates with commas, e.g.
46//
47// #define FOO(Type, Name) UNPAREN(Type) Name;
48//
49// will work with both
50//
51// FOO(int, x);
52// FOO((Foo<int, double, float>), x);
53#define UNPAREN(X) CONCAT(DROP_, UNPAREN_ X)
54#define UNPAREN_(...) UNPAREN_ __VA_ARGS__
55#define DROP_UNPAREN_
56
57#define OFFSET_OF(type, field) offsetof(type, field)
58
59// A comma, to be used in macro arguments where it would otherwise be
60// interpreted as separator of arguments.
61#define LITERAL_COMMA ,
62
63// The arraysize(arr) macro returns the # of elements in an array arr.
64// The expression is a compile-time constant, and therefore can be
65// used in defining new arrays, for example. If you use arraysize on
66// a pointer by mistake, you will get a compile-time error.
67#define arraysize(array) (sizeof(ArraySizeHelper(array)))
68
69// This template function declaration is used in defining arraysize.
70// Note that the function doesn't need an implementation, as we only
71// use its type.
72template <typename T, size_t N>
73char (&ArraySizeHelper(T (&array)[N]))[N];
74
75#if !V8_CC_MSVC
76// That gcc wants both of these prototypes seems mysterious. VC, for
77// its part, can't decide which to use (another mystery). Matching of
78// template overloads: the final frontier.
79template <typename T, size_t N>
80char (&ArraySizeHelper(const T (&array)[N]))[N];
81#endif
82
83// This is an equivalent to C++20's std::bit_cast<>(), but with additional
84// warnings. It morally does what `*reinterpret_cast<Dest*>(&source)` does, but
85// the cast/deref pair is undefined behavior, while bit_cast<>() isn't.
86//
87// This is not a magic "get out of UB free" card. This must only be used on
88// values, not on references or pointers. For pointers, use
89// reinterpret_cast<>(), or static_cast<>() when casting between void* and other
90// pointers, and then look at https://eel.is/c++draft/basic.lval#11 as that's
91// probably UB also.
92namespace v8::base {
93
94template <class Dest, class Source>
95V8_INLINE Dest bit_cast(Source const& 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");
102 static_assert(
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");
107 static_assert(
108 std::is_trivially_copyable_v<Dest>,
109 "bit_cast requires the destination type to be trivially copyable");
110
111#if V8_HAS_BUILTIN_BIT_CAST
112 return __builtin_bit_cast(Dest, source);
113#else
114 Dest dest;
115 memcpy(&dest, &source, sizeof(dest));
116 return dest;
117#endif
118}
119
120} // namespace v8::base
121
122// Explicitly declare the assignment operator as deleted.
123// Note: This macro is deprecated and will be removed soon. Please explicitly
124// delete the assignment operator instead.
125#define DISALLOW_ASSIGN(TypeName) TypeName& operator=(const TypeName&) = delete
126
127// Explicitly declare all implicit constructors as deleted, namely the
128// default constructor, copy constructor and operator= functions.
129// This is especially useful for classes containing only static methods.
130#define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \
131 TypeName() = delete; \
132 TypeName(const TypeName&) = delete; \
133 DISALLOW_ASSIGN(TypeName)
134
135// Disallow copying a type, but provide default construction, move construction
136// and move assignment. Especially useful for move-only structs.
137#define MOVE_ONLY_WITH_DEFAULT_CONSTRUCTORS(TypeName) \
138 TypeName() = default; \
139 MOVE_ONLY_NO_DEFAULT_CONSTRUCTOR(TypeName)
140
141// Disallow copying a type, and only provide move construction and move
142// assignment. Especially useful for move-only structs.
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)
148
149// A macro to disallow the dynamic allocation.
150// This should be used in the private: declarations for a class
151// Declaring operator new and delete as deleted is not spec compliant.
152// Extract from 3.2.2 of C++11 spec:
153// [...] A non-placement deallocation function for a class is
154// odr-used by the definition of the destructor of that class, [...]
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(); }
160
161// Define V8_USE_ADDRESS_SANITIZER macro.
162#if defined(__has_feature)
163#if __has_feature(address_sanitizer)
164#define V8_USE_ADDRESS_SANITIZER 1
165#endif
166#endif
167
168// Define V8_USE_HWADDRESS_SANITIZER macro.
169#if defined(__has_feature)
170#if __has_feature(hwaddress_sanitizer)
171#define V8_USE_HWADDRESS_SANITIZER 1
172#endif
173#endif
174
175// Define V8_USE_MEMORY_SANITIZER macro.
176#if defined(__has_feature)
177#if __has_feature(memory_sanitizer)
178#define V8_USE_MEMORY_SANITIZER 1
179#endif
180#endif
181
182// Define V8_USE_UNDEFINED_BEHAVIOR_SANITIZER macro.
183#if defined(__has_feature)
184#if __has_feature(undefined_behavior_sanitizer)
185#define V8_USE_UNDEFINED_BEHAVIOR_SANITIZER 1
186#endif
187#endif
188
189// Define V8_USE_SAFE_STACK macro.
190#if defined(__has_feature)
191#if __has_feature(safe_stack)
192#define V8_USE_SAFE_STACK 1
193#endif // __has_feature(safe_stack)
194#endif // defined(__has_feature)
195
196// DISABLE_CFI_PERF -- Disable Control Flow Integrity checks for Perf reasons.
197#define DISABLE_CFI_PERF V8_CLANG_NO_SANITIZE("cfi")
198
199// DISABLE_CFI_ICALL -- Disable Control Flow Integrity indirect call checks,
200// useful because calls into JITed code can not be CFI verified. Same for
201// UBSan's function pointer type checks.
202#ifdef V8_OS_WIN
203// On Windows, also needs __declspec(guard(nocf)) for CFG.
204#define DISABLE_CFI_ICALL \
205 V8_CLANG_NO_SANITIZE("cfi-icall") \
206 V8_CLANG_NO_SANITIZE("function") \
207 __declspec(guard(nocf))
208#else
209#define DISABLE_CFI_ICALL \
210 V8_CLANG_NO_SANITIZE("cfi-icall") \
211 V8_CLANG_NO_SANITIZE("function")
212#endif
213
214// V8_PRETTY_FUNCTION_VALUE_OR(ELSE) emits a pretty function value, if
215// available for this compiler, otherwise it emits ELSE.
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__
220#else
221#define V8_PRETTY_FUNCTION_VALUE_OR(ELSE) ELSE
222#endif
223
224namespace v8 {
225namespace base {
226
227// Note that some implementations of std::is_trivially_copyable mandate that at
228// least one of the copy constructor, move constructor, copy assignment or move
229// assignment is non-deleted, while others do not. Be aware that also
230// base::is_trivially_copyable will differ for these cases.
231template <typename T>
233#if V8_CC_MSVC || (__GNUC__ == 12 && __GNUC_MINOR__ <= 2)
234 // Unfortunately, MSVC 2015 is broken in that std::is_trivially_copyable can
235 // be false even though it should be true according to the standard.
236 // (status at 2018-02-26, observed on the msvc waterfall bot).
237 // Interestingly, the lower-level primitives used below are working as
238 // intended, so we reimplement this according to the standard.
239 // See also https://developercommunity.visualstudio.com/content/problem/
240 // 170883/msvc-type-traits-stdis-trivial-is-bugged.html.
241 //
242 // GCC 12.1 and 12.2 are broken too, they are shipped by some stable Linux
243 // distributions, so the same polyfill is also used.
244 // See
245 // https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=aeba3e009b0abfccaf01797556445dbf891cc8dc
246 static constexpr bool value =
247 // Copy constructor is trivial or deleted.
248 (std::is_trivially_copy_constructible<T>::value ||
249 !std::is_copy_constructible<T>::value) &&
250 // Copy assignment operator is trivial or deleted.
251 (std::is_trivially_copy_assignable<T>::value ||
252 !std::is_copy_assignable<T>::value) &&
253 // Move constructor is trivial or deleted.
254 (std::is_trivially_move_constructible<T>::value ||
255 !std::is_move_constructible<T>::value) &&
256 // Move assignment operator is trivial or deleted.
257 (std::is_trivially_move_assignable<T>::value ||
258 !std::is_move_assignable<T>::value) &&
259 // (Some implementations mandate that one of the above is non-deleted, but
260 // the standard does not, so let's skip this check.)
261 // Trivial non-deleted destructor.
262 std::is_trivially_destructible<T>::value;
263#else
264 static constexpr bool value = std::is_trivially_copyable<T>::value;
265#endif
266};
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")
273
274// Be aware that base::is_trivially_destructible will differ from
275// std::is_trivially_destructible for cases like DirectHandle<T>.
276template <typename T>
277struct is_trivially_destructible : public std::is_trivially_destructible<T> {};
278
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")
285
286// The USE(x, ...) template is used to silence C++ compiler warnings
287// issued for (yet) unused variables (typically parameters).
288// The arguments are guaranteed to be evaluated from left to right.
289struct Use {
290 template <typename T>
291 constexpr Use(T&&) {} // NOLINT(runtime/explicit)
292};
293#define USE(...) \
294 do { \
295 ::v8::base::Use unused_tmp_array_for_use_macro[]{__VA_ARGS__}; \
296 (void)unused_tmp_array_for_use_macro; \
297 } while (false)
298
299} // namespace base
300} // namespace v8
301
302// implicit_cast<A>(x) triggers an implicit cast from {x} to type {A}. This is
303// useful in situations where static_cast<A>(x) would do too much.
304// Only use this for cheap-to-copy types, or use move semantics explicitly.
305template <class A>
307 return x;
308}
309
310// Define our own macros for writing 64-bit constants. This is less fragile
311// than defining __STDC_CONSTANT_MACROS before including <stdint.h>, and it
312// works on compilers that don't have it (like MSVC).
313#if V8_CC_MSVC
314# if V8_HOST_ARCH_64_BIT
315# define V8_PTR_PREFIX "ll"
316# else
317# define V8_PTR_PREFIX ""
318# endif // V8_HOST_ARCH_64_BIT
319#elif V8_CC_MINGW64
320# define V8_PTR_PREFIX "I64"
321#elif V8_HOST_ARCH_64_BIT
322# define V8_PTR_PREFIX "l"
323#else
324#if V8_OS_AIX
325#define V8_PTR_PREFIX "l"
326#else
327# define V8_PTR_PREFIX ""
328#endif
329#endif
330
331#define V8PRIxPTR V8_PTR_PREFIX "x"
332#define V8PRIdPTR V8_PTR_PREFIX "d"
333#define V8PRIuPTR V8_PTR_PREFIX "u"
334
335#if V8_TARGET_ARCH_64_BIT
336#define V8_PTR_HEX_DIGITS 12
337#define V8PRIxPTR_FMT "0x%012" V8PRIxPTR
338#else
339#define V8_PTR_HEX_DIGITS 8
340#define V8PRIxPTR_FMT "0x%08" V8PRIxPTR
341#endif
342
343// ptrdiff_t is 't' according to the standard, but MSVC uses 'I'.
344#if V8_CC_MSVC
345#define V8PRIxPTRDIFF "Ix"
346#define V8PRIdPTRDIFF "Id"
347#define V8PRIuPTRDIFF "Iu"
348#else
349#define V8PRIxPTRDIFF "tx"
350#define V8PRIdPTRDIFF "td"
351#define V8PRIuPTRDIFF "tu"
352#endif
353
354// Fix for Mac OS X defining uintptr_t as "unsigned long":
355#if V8_OS_DARWIN
356#undef V8PRIxPTR
357#define V8PRIxPTR "lx"
358#undef V8PRIdPTR
359#define V8PRIdPTR "ld"
360#undef V8PRIuPTR
361#define V8PRIuPTR "lxu"
362#endif
363
364// Make a uint64 from two uint32_t halves.
365inline uint64_t make_uint64(uint32_t high, uint32_t low) {
366 return (uint64_t{high} << 32) + low;
367}
368
369// Return the largest multiple of m which is <= x.
370template <typename T>
371constexpr T RoundDown(T x, intptr_t m) {
372 static_assert(std::is_integral<T>::value);
373 // m must be a power of two.
374 DCHECK(m != 0 && ((m & (m - 1)) == 0));
375 return x & static_cast<T>(-m);
376}
377template <intptr_t m, typename T>
378constexpr T RoundDown(T x) {
379 static_assert(std::is_integral<T>::value);
380 // m must be a power of two.
381 static_assert(m != 0 && ((m & (m - 1)) == 0));
382 return x & static_cast<T>(-m);
383}
384
385// Return the smallest multiple of m which is >= x.
386template <typename T>
387constexpr T RoundUp(T x, intptr_t m) {
388 static_assert(std::is_integral<T>::value);
389 DCHECK_GE(x, 0);
390 DCHECK_GE(std::numeric_limits<T>::max() - x, m - 1); // Overflow check.
391 return RoundDown<T>(static_cast<T>(x + (m - 1)), m);
392}
393
394template <intptr_t m, typename T>
395constexpr T RoundUp(T x) {
396 static_assert(std::is_integral<T>::value);
397 DCHECK_GE(x, 0);
398 DCHECK_GE(std::numeric_limits<T>::max() - x, m - 1); // Overflow check.
399 return RoundDown<m, T>(static_cast<T>(x + (m - 1)));
400}
401
402template <typename T, typename U>
403constexpr inline bool IsAligned(T value, U alignment) {
404 return (value & (alignment - 1)) == 0;
405}
406
407inline void* AlignedAddress(void* address, size_t alignment) {
408 return reinterpret_cast<void*>(
409 RoundDown(reinterpret_cast<uintptr_t>(address), alignment));
410}
411
412inline void* RoundUpAddress(void* address, size_t alignment) {
413 return reinterpret_cast<void*>(
414 RoundUp(reinterpret_cast<uintptr_t>(address), alignment));
415}
416
417// Bounds checks for float to integer conversions, which does truncation. Hence,
418// the range of legal values is (min - 1, max + 1).
419template <typename int_t, typename float_t, typename biggest_int_t = int64_t>
420bool is_inbounds(float_t v) {
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());
433 // Using USE(var) is only a workaround for a GCC 8.1 bug.
434 USE(kLowerBoundIsMin);
435 USE(kUpperBoundIsMax);
436 return (kLowerBoundIsMin ? (kLowerBound <= v) : (kLowerBound < v)) &&
437 (kUpperBoundIsMax ? (v <= kUpperBound) : (v < kUpperBound));
438}
439
440#ifdef V8_OS_WIN
441
442// Setup for Windows shared library export.
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)
448#else
449#define V8_EXPORT_PRIVATE
450#endif // BUILDING_V8_SHARED
451
452#else // V8_OS_WIN
453
454// Setup for Linux shared library export.
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
459#else
460#define V8_EXPORT_PRIVATE
461#define V8_EXPORT_ENUM
462#endif // V8_HAS_ATTRIBUTE_VISIBILITY && ..
463
464#endif // V8_OS_WIN
465
466// Defines IF_WASM, to be used in macro lists for elements that should only be
467// there if WebAssembly is enabled.
468#if V8_ENABLE_WEBASSEMBLY
469// EXPAND is needed to work around MSVC's broken __VA_ARGS__ expansion.
470#define IF_WASM(V, ...) EXPAND(V(__VA_ARGS__))
471#else
472#define IF_WASM(V, ...)
473#endif // V8_ENABLE_WEBASSEMBLY
474
475#ifdef V8_ENABLE_DRUMBRAKE
476#define IF_WASM_DRUMBRAKE(V, ...) EXPAND(V(__VA_ARGS__))
477#else
478#define IF_WASM_DRUMBRAKE(V, ...)
479#endif // V8_ENABLE_DRUMBRAKE
480
481#if defined(V8_ENABLE_DRUMBRAKE) && !defined(V8_DRUMBRAKE_BOUNDS_CHECKS)
482#define IF_WASM_DRUMBRAKE_INSTR_HANDLER(V, ...) EXPAND(V(__VA_ARGS__))
483#else
484#define IF_WASM_DRUMBRAKE_INSTR_HANDLER(V, ...)
485#endif // V8_ENABLE_DRUMBRAKE && !V8_DRUMBRAKE_BOUNDS_CHECKS
486
487// Defines IF_TSAN, to be used in macro lists for elements that should only be
488// there if TSAN is enabled.
489#ifdef V8_IS_TSAN
490// EXPAND is needed to work around MSVC's broken __VA_ARGS__ expansion.
491#define IF_TSAN(V, ...) EXPAND(V(__VA_ARGS__))
492#else
493#define IF_TSAN(V, ...)
494#endif // V8_IS_TSAN
495
496// Defines IF_INTL, to be used in macro lists for elements that should only be
497// there if INTL is enabled.
498#ifdef V8_INTL_SUPPORT
499// EXPAND is needed to work around MSVC's broken __VA_ARGS__ expansion.
500#define IF_INTL(V, ...) EXPAND(V(__VA_ARGS__))
501#else
502#define IF_INTL(V, ...)
503#endif // V8_INTL_SUPPORT
504
505// Defines IF_SHADOW_STACK, to be used in macro lists for elements that should
506// only be there if CET shadow stack is enabled.
507#ifdef V8_ENABLE_CET_SHADOW_STACK
508// EXPAND is needed to work around MSVC's broken __VA_ARGS__ expansion.
509#define IF_SHADOW_STACK(V, ...) EXPAND(V(__VA_ARGS__))
510#else
511#define IF_SHADOW_STACK(V, ...)
512#endif // V8_ENABLE_CET_SHADOW_STACK
513
514// Defines IF_TARGET_ARCH_64_BIT, to be used in macro lists for elements that
515// should only be there if the target architecture is a 64-bit one.
516#if V8_TARGET_ARCH_64_BIT
517// EXPAND is needed to work around MSVC's broken __VA_ARGS__ expansion.
518#define IF_TARGET_ARCH_64_BIT(V, ...) EXPAND(V(__VA_ARGS__))
519#else
520#define IF_TARGET_ARCH_64_BIT(V, ...)
521#endif // V8_TARGET_ARCH_64_BIT
522
523// Defines IF_V8_WASM_RANDOM_FUZZERS and IF_NO_V8_WASM_RANDOM_FUZZERS, to be
524// used in macro lists for elements that should only be there/absent when
525// building the Wasm fuzzers.
526#ifdef V8_WASM_RANDOM_FUZZERS
527// EXPAND is needed to work around MSVC's broken __VA_ARGS__ expansion.
528#define IF_V8_WASM_RANDOM_FUZZERS(V, ...) EXPAND(V(__VA_ARGS__))
529#define IF_NO_V8_WASM_RANDOM_FUZZERS(V, ...)
530#else
531#define IF_V8_WASM_RANDOM_FUZZERS(V, ...)
532#define IF_NO_V8_WASM_RANDOM_FUZZERS(V, ...) EXPAND(V(__VA_ARGS__))
533#endif // V8_WASM_RANDOM_FUZZERS
534
535#ifdef GOOGLE3
536// Disable FRIEND_TEST macro in Google3.
537#define FRIEND_TEST(test_case_name, test_name)
538#endif
539
540#endif // V8_BASE_MACROS_H_
int x
int m
Definition mul-fft.cc:294
V8_INLINE Dest bit_cast(Source const &source)
Definition macros.h:95
#define DCHECK_GE(v1, v2)
Definition logging.h:488
#define DCHECK(condition)
Definition logging.h:482
char(& ArraySizeHelper(T(&array)[N]))[N]
void * RoundUpAddress(void *address, size_t alignment)
Definition macros.h:412
#define USE(...)
Definition macros.h:293
V8_INLINE A implicit_cast(A x)
Definition macros.h:306
constexpr T RoundUp(T x, intptr_t m)
Definition macros.h:387
void * AlignedAddress(void *address, size_t alignment)
Definition macros.h:407
constexpr T RoundDown(T x, intptr_t m)
Definition macros.h:371
constexpr bool IsAligned(T value, U alignment)
Definition macros.h:403
uint64_t make_uint64(uint32_t high, uint32_t low)
Definition macros.h:365
bool is_inbounds(float_t v)
Definition macros.h:420
constexpr Use(T &&)
Definition macros.h:291
#define V8_INLINE
Definition v8config.h:500