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
10#include "src/base/compiler-specific.h"
11#include "src/base/format-macros.h"
12#include "src/base/logging.h"
13
14// No-op macro which is used to work around MSVC's funky VA_ARGS support.
15#define EXPAND(x) x
16
17// This macro does nothing. That's all.
18#define NOTHING(...)
19
20// TODO(all) Replace all uses of this macro with C++'s offsetof. To do that, we
21// have to make sure that only standard-layout types and simple field
22// designators are used.
23#define OFFSET_OF(type, field) \
24 (reinterpret_cast<intptr_t>(&(reinterpret_cast<type*>(16)->field)) - 16)
25
26
27// The arraysize(arr) macro returns the # of elements in an array arr.
28// The expression is a compile-time constant, and therefore can be
29// used in defining new arrays, for example. If you use arraysize on
30// a pointer by mistake, you will get a compile-time error.
31#define arraysize(array) (sizeof(ArraySizeHelper(array)))
32
33
34// This template function declaration is used in defining arraysize.
35// Note that the function doesn't need an implementation, as we only
36// use its type.
37template <typename T, size_t N>
38char (&ArraySizeHelper(T (&array)[N]))[N];
39
40
41#if !V8_CC_MSVC
42// That gcc wants both of these prototypes seems mysterious. VC, for
43// its part, can't decide which to use (another mystery). Matching of
44// template overloads: the final frontier.
45template <typename T, size_t N>
46char (&ArraySizeHelper(const T (&array)[N]))[N];
47#endif
48
49// bit_cast<Dest,Source> is a template function that implements the
50// equivalent of "*reinterpret_cast<Dest*>(&source)". We need this in
51// very low-level functions like the protobuf library and fast math
52// support.
53//
54// float f = 3.14159265358979;
55// int i = bit_cast<int32>(f);
56// // i = 0x40490fdb
57//
58// The classical address-casting method is:
59//
60// // WRONG
61// float f = 3.14159265358979; // WRONG
62// int i = * reinterpret_cast<int*>(&f); // WRONG
63//
64// The address-casting method actually produces undefined behavior
65// according to ISO C++ specification section 3.10 -15 -. Roughly, this
66// section says: if an object in memory has one type, and a program
67// accesses it with a different type, then the result is undefined
68// behavior for most values of "different type".
69//
70// This is true for any cast syntax, either *(int*)&f or
71// *reinterpret_cast<int*>(&f). And it is particularly true for
72// conversions between integral lvalues and floating-point lvalues.
73//
74// The purpose of 3.10 -15- is to allow optimizing compilers to assume
75// that expressions with different types refer to different memory. gcc
76// 4.0.1 has an optimizer that takes advantage of this. So a
77// non-conforming program quietly produces wildly incorrect output.
78//
79// The problem is not the use of reinterpret_cast. The problem is type
80// punning: holding an object in memory of one type and reading its bits
81// back using a different type.
82//
83// The C++ standard is more subtle and complex than this, but that
84// is the basic idea.
85//
86// Anyways ...
87//
88// bit_cast<> calls memcpy() which is blessed by the standard,
89// especially by the example in section 3.9 . Also, of course,
90// bit_cast<> wraps up the nasty logic in one place.
91//
92// Fortunately memcpy() is very fast. In optimized mode, with a
93// constant size, gcc 2.95.3, gcc 4.0.1, and msvc 7.1 produce inline
94// code with the minimal amount of data movement. On a 32-bit system,
95// memcpy(d,s,4) compiles to one load and one store, and memcpy(d,s,8)
96// compiles to two loads and two stores.
97//
98// I tested this code with gcc 2.95.3, gcc 4.0.1, icc 8.1, and msvc 7.1.
99//
100// WARNING: if Dest or Source is a non-POD type, the result of the memcpy
101// is likely to surprise you.
102template <class Dest, class Source>
103V8_INLINE Dest bit_cast(Source const& source) {
104 static_assert(sizeof(Dest) == sizeof(Source),
105 "source and dest must be same size");
106 Dest dest;
107 memcpy(&dest, &source, sizeof(dest));
108 return dest;
109}
110
111// Explicitly declare the assignment operator as deleted.
112#define DISALLOW_ASSIGN(TypeName) TypeName& operator=(const TypeName&) = delete
113
114// Explicitly declare the copy constructor and assignment operator as deleted.
115// This also deletes the implicit move constructor and implicit move assignment
116// operator, but still allows to manually define them.
117#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
118 TypeName(const TypeName&) = delete; \
119 DISALLOW_ASSIGN(TypeName)
120
121// Explicitly declare all implicit constructors as deleted, namely the
122// default constructor, copy constructor and operator= functions.
123// This is especially useful for classes containing only static methods.
124#define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \
125 TypeName() = delete; \
126 DISALLOW_COPY_AND_ASSIGN(TypeName)
127
128// Disallow copying a type, but provide default construction, move construction
129// and move assignment. Especially useful for move-only structs.
130#define MOVE_ONLY_WITH_DEFAULT_CONSTRUCTORS(TypeName) \
131 TypeName() = default; \
132 MOVE_ONLY_NO_DEFAULT_CONSTRUCTOR(TypeName)
133
134// Disallow copying a type, and only provide move construction and move
135// assignment. Especially useful for move-only structs.
136#define MOVE_ONLY_NO_DEFAULT_CONSTRUCTOR(TypeName) \
137 TypeName(TypeName&&) V8_NOEXCEPT = default; \
138 TypeName& operator=(TypeName&&) V8_NOEXCEPT = default; \
139 DISALLOW_COPY_AND_ASSIGN(TypeName)
140
141// A macro to disallow the dynamic allocation.
142// This should be used in the private: declarations for a class
143// Declaring operator new and delete as deleted is not spec compliant.
144// Extract from 3.2.2 of C++11 spec:
145// [...] A non-placement deallocation function for a class is
146// odr-used by the definition of the destructor of that class, [...]
147#define DISALLOW_NEW_AND_DELETE() \
148 void* operator new(size_t) { base::OS::Abort(); } \
149 void* operator new[](size_t) { base::OS::Abort(); } \
150 void operator delete(void*, size_t) { base::OS::Abort(); } \
151 void operator delete[](void*, size_t) { base::OS::Abort(); }
152
153// Define V8_USE_ADDRESS_SANITIZER macro.
154#if defined(__has_feature)
155#if __has_feature(address_sanitizer)
156#define V8_USE_ADDRESS_SANITIZER 1
157#endif
158#endif
159
160// Define DISABLE_ASAN macro.
161#ifdef V8_USE_ADDRESS_SANITIZER
162#define DISABLE_ASAN __attribute__((no_sanitize_address))
163#else
164#define DISABLE_ASAN
165#endif
166
167// Define V8_USE_MEMORY_SANITIZER macro.
168#if defined(__has_feature)
169#if __has_feature(memory_sanitizer)
170#define V8_USE_MEMORY_SANITIZER 1
171#endif
172#endif
173
174// Helper macro to define no_sanitize attributes only with clang.
175#if defined(__clang__) && defined(__has_attribute)
176#if __has_attribute(no_sanitize)
177#define CLANG_NO_SANITIZE(what) __attribute__((no_sanitize(what)))
178#endif
179#endif
180#if !defined(CLANG_NO_SANITIZE)
181#define CLANG_NO_SANITIZE(what)
182#endif
183
184// DISABLE_CFI_PERF -- Disable Control Flow Integrity checks for Perf reasons.
185#define DISABLE_CFI_PERF CLANG_NO_SANITIZE("cfi")
186
187// DISABLE_CFI_ICALL -- Disable Control Flow Integrity indirect call checks,
188// useful because calls into JITed code can not be CFI verified.
189#define DISABLE_CFI_ICALL CLANG_NO_SANITIZE("cfi-icall")
190
191#if V8_CC_GNU
192#define V8_IMMEDIATE_CRASH() __builtin_trap()
193#else
194#define V8_IMMEDIATE_CRASH() ((void(*)())0)()
195#endif
196
197// A convenience wrapper around static_assert without a string message argument.
198// Once C++17 becomes the default, this macro can be removed in favor of the
199// new static_assert(condition) overload.
200#define STATIC_ASSERT(test) static_assert(test, #test)
201
202namespace v8 {
203namespace base {
204
205// Note that some implementations of std::is_trivially_copyable mandate that at
206// least one of the copy constructor, move constructor, copy assignment or move
207// assignment is non-deleted, while others do not. Be aware that also
208// base::is_trivially_copyable will differ for these cases.
209template <typename T>
210struct is_trivially_copyable {
211#if V8_CC_MSVC
212 // Unfortunately, MSVC 2015 is broken in that std::is_trivially_copyable can
213 // be false even though it should be true according to the standard.
214 // (status at 2018-02-26, observed on the msvc waterfall bot).
215 // Interestingly, the lower-level primitives used below are working as
216 // intended, so we reimplement this according to the standard.
217 // See also https://developercommunity.visualstudio.com/content/problem/
218 // 170883/msvc-type-traits-stdis-trivial-is-bugged.html.
219 static constexpr bool value =
220 // Copy constructor is trivial or deleted.
221 (std::is_trivially_copy_constructible<T>::value ||
222 !std::is_copy_constructible<T>::value) &&
223 // Copy assignment operator is trivial or deleted.
224 (std::is_trivially_copy_assignable<T>::value ||
225 !std::is_copy_assignable<T>::value) &&
226 // Move constructor is trivial or deleted.
227 (std::is_trivially_move_constructible<T>::value ||
228 !std::is_move_constructible<T>::value) &&
229 // Move assignment operator is trivial or deleted.
230 (std::is_trivially_move_assignable<T>::value ||
231 !std::is_move_assignable<T>::value) &&
232 // (Some implementations mandate that one of the above is non-deleted, but
233 // the standard does not, so let's skip this check.)
234 // Trivial non-deleted destructor.
235 std::is_trivially_destructible<T>::value;
236
237#elif defined(__GNUC__) && __GNUC__ < 5
238 // WARNING:
239 // On older libstdc++ versions, there is no way to correctly implement
240 // is_trivially_copyable. The workaround below is an approximation (neither
241 // over- nor underapproximation). E.g. it wrongly returns true if the move
242 // constructor is non-trivial, and it wrongly returns false if the copy
243 // constructor is deleted, but copy assignment is trivial.
244 // TODO(rongjie) Remove this workaround once we require gcc >= 5.0
245 static constexpr bool value =
246 __has_trivial_copy(T) && __has_trivial_destructor(T);
247
248#else
249 static constexpr bool value = std::is_trivially_copyable<T>::value;
250#endif
251};
252#if defined(__GNUC__) && __GNUC__ < 5
253// On older libstdc++ versions, base::is_trivially_copyable<T>::value is only an
254// approximation (see above), so make ASSERT_{NOT_,}TRIVIALLY_COPYABLE a noop.
255#define ASSERT_TRIVIALLY_COPYABLE(T) static_assert(true, "check disabled")
256#define ASSERT_NOT_TRIVIALLY_COPYABLE(T) static_assert(true, "check disabled")
257#else
258#define ASSERT_TRIVIALLY_COPYABLE(T) \
259 static_assert(::v8::base::is_trivially_copyable<T>::value, \
260 #T " should be trivially copyable")
261#define ASSERT_NOT_TRIVIALLY_COPYABLE(T) \
262 static_assert(!::v8::base::is_trivially_copyable<T>::value, \
263 #T " should not be trivially copyable")
264#endif
265
266// The USE(x, ...) template is used to silence C++ compiler warnings
267// issued for (yet) unused variables (typically parameters).
268// The arguments are guaranteed to be evaluated from left to right.
269struct Use {
270 template <typename T>
271 Use(T&&) {} // NOLINT(runtime/explicit)
272};
273#define USE(...) \
274 do { \
275 ::v8::base::Use unused_tmp_array_for_use_macro[]{__VA_ARGS__}; \
276 (void)unused_tmp_array_for_use_macro; \
277 } while (false)
278
279// Evaluate the instantiations of an expression with parameter packs.
280// Since USE has left-to-right evaluation order of it's arguments,
281// the parameter pack is iterated from left to right and side effects
282// have defined behavior.
283#define ITERATE_PACK(...) USE(0, ((__VA_ARGS__), 0)...)
284
285} // namespace base
286} // namespace v8
287
288// implicit_cast<A>(x) triggers an implicit cast from {x} to type {A}. This is
289// useful in situations where static_cast<A>(x) would do too much.
290// Only use this for cheap-to-copy types, or use move semantics explicitly.
291template <class A>
292V8_INLINE A implicit_cast(A x) {
293 return x;
294}
295
296// Define our own macros for writing 64-bit constants. This is less fragile
297// than defining __STDC_CONSTANT_MACROS before including <stdint.h>, and it
298// works on compilers that don't have it (like MSVC).
299#if V8_CC_MSVC
300# if V8_HOST_ARCH_64_BIT
301# define V8_PTR_PREFIX "ll"
302# else
303# define V8_PTR_PREFIX ""
304# endif // V8_HOST_ARCH_64_BIT
305#elif V8_CC_MINGW64
306# define V8_PTR_PREFIX "I64"
307#elif V8_HOST_ARCH_64_BIT
308# define V8_PTR_PREFIX "l"
309#else
310#if V8_OS_AIX
311#define V8_PTR_PREFIX "l"
312#else
313# define V8_PTR_PREFIX ""
314#endif
315#endif
316
317#define V8PRIxPTR V8_PTR_PREFIX "x"
318#define V8PRIdPTR V8_PTR_PREFIX "d"
319#define V8PRIuPTR V8_PTR_PREFIX "u"
320
321#if V8_TARGET_ARCH_64_BIT
322#define V8_PTR_HEX_DIGITS 12
323#define V8PRIxPTR_FMT "0x%012" V8PRIxPTR
324#else
325#define V8_PTR_HEX_DIGITS 8
326#define V8PRIxPTR_FMT "0x%08" V8PRIxPTR
327#endif
328
329// ptrdiff_t is 't' according to the standard, but MSVC uses 'I'.
330#if V8_CC_MSVC
331#define V8PRIxPTRDIFF "Ix"
332#define V8PRIdPTRDIFF "Id"
333#define V8PRIuPTRDIFF "Iu"
334#else
335#define V8PRIxPTRDIFF "tx"
336#define V8PRIdPTRDIFF "td"
337#define V8PRIuPTRDIFF "tu"
338#endif
339
340// Fix for Mac OS X defining uintptr_t as "unsigned long":
341#if V8_OS_MACOSX
342#undef V8PRIxPTR
343#define V8PRIxPTR "lx"
344#undef V8PRIdPTR
345#define V8PRIdPTR "ld"
346#undef V8PRIuPTR
347#define V8PRIuPTR "lxu"
348#endif
349
350// The following macro works on both 32 and 64-bit platforms.
351// Usage: instead of writing 0x1234567890123456
352// write V8_2PART_UINT64_C(0x12345678,90123456);
353#define V8_2PART_UINT64_C(a, b) (((static_cast<uint64_t>(a) << 32) + 0x##b##u))
354
355// Return the largest multiple of m which is <= x.
356template <typename T>
357inline T RoundDown(T x, intptr_t m) {
358 STATIC_ASSERT(std::is_integral<T>::value);
359 // m must be a power of two.
360 DCHECK(m != 0 && ((m & (m - 1)) == 0));
361 return x & -m;
362}
363template <intptr_t m, typename T>
364constexpr inline T RoundDown(T x) {
365 STATIC_ASSERT(std::is_integral<T>::value);
366 // m must be a power of two.
367 STATIC_ASSERT(m != 0 && ((m & (m - 1)) == 0));
368 return x & -m;
369}
370
371// Return the smallest multiple of m which is >= x.
372template <typename T>
373inline T RoundUp(T x, intptr_t m) {
374 STATIC_ASSERT(std::is_integral<T>::value);
375 return RoundDown<T>(static_cast<T>(x + m - 1), m);
376}
377template <intptr_t m, typename T>
378constexpr inline T RoundUp(T x) {
379 STATIC_ASSERT(std::is_integral<T>::value);
380 return RoundDown<m, T>(static_cast<T>(x + (m - 1)));
381}
382
383template <typename T, typename U>
384constexpr inline bool IsAligned(T value, U alignment) {
385 return (value & (alignment - 1)) == 0;
386}
387
388inline void* AlignedAddress(void* address, size_t alignment) {
389 // The alignment must be a power of two.
390 DCHECK_EQ(alignment & (alignment - 1), 0u);
391 return reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(address) &
392 ~static_cast<uintptr_t>(alignment - 1));
393}
394
395// Bounds checks for float to integer conversions, which does truncation. Hence,
396// the range of legal values is (min - 1, max + 1).
397template <typename int_t, typename float_t, typename biggest_int_t = int64_t>
398bool is_inbounds(float_t v) {
399 static_assert(sizeof(int_t) < sizeof(biggest_int_t),
400 "int_t can't be bounds checked by the compiler");
401 constexpr float_t kLowerBound =
402 static_cast<float_t>(std::numeric_limits<int_t>::min()) - 1;
403 constexpr float_t kUpperBound =
404 static_cast<float_t>(std::numeric_limits<int_t>::max()) + 1;
405 constexpr bool kLowerBoundIsMin =
406 static_cast<biggest_int_t>(kLowerBound) ==
407 static_cast<biggest_int_t>(std::numeric_limits<int_t>::min());
408 constexpr bool kUpperBoundIsMax =
409 static_cast<biggest_int_t>(kUpperBound) ==
410 static_cast<biggest_int_t>(std::numeric_limits<int_t>::max());
411 return (kLowerBoundIsMin ? (kLowerBound <= v) : (kLowerBound < v)) &&
412 (kUpperBoundIsMax ? (v <= kUpperBound) : (v < kUpperBound));
413}
414
415#ifdef V8_OS_WIN
416
417// Setup for Windows shared library export.
418#ifdef BUILDING_V8_SHARED
419#define V8_EXPORT_PRIVATE __declspec(dllexport)
420#elif USING_V8_SHARED
421#define V8_EXPORT_PRIVATE __declspec(dllimport)
422#else
423#define V8_EXPORT_PRIVATE
424#endif // BUILDING_V8_SHARED
425
426#else // V8_OS_WIN
427
428// Setup for Linux shared library export.
429#if V8_HAS_ATTRIBUTE_VISIBILITY
430#ifdef BUILDING_V8_SHARED
431#define V8_EXPORT_PRIVATE __attribute__((visibility("default")))
432#else
433#define V8_EXPORT_PRIVATE
434#endif
435#else
436#define V8_EXPORT_PRIVATE
437#endif
438
439#endif // V8_OS_WIN
440
441#endif // V8_BASE_MACROS_H_
442