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. |
37 | template <typename T, size_t N> |
38 | char (&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. |
45 | template <typename T, size_t N> |
46 | char (&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. |
102 | template <class Dest, class Source> |
103 | V8_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 | |
202 | namespace v8 { |
203 | namespace 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. |
209 | template <typename T> |
210 | struct 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. |
269 | struct 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. |
291 | template <class A> |
292 | V8_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. |
356 | template <typename T> |
357 | inline 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 | } |
363 | template <intptr_t m, typename T> |
364 | constexpr 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. |
372 | template <typename T> |
373 | inline 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 | } |
377 | template <intptr_t m, typename T> |
378 | constexpr 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 | |
383 | template <typename T, typename U> |
384 | constexpr inline bool IsAligned(T value, U alignment) { |
385 | return (value & (alignment - 1)) == 0; |
386 | } |
387 | |
388 | inline 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). |
397 | template <typename int_t, typename float_t, typename biggest_int_t = int64_t> |
398 | bool 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 | |