V8 API Reference, 7.2.502.16 (for Deno 0.2.4)
macros.h
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 #define DISALLOW_COPY_AND_ASSIGN(TypeName) \
116  TypeName(const TypeName&) = delete; \
117  DISALLOW_ASSIGN(TypeName)
118 
119 // Explicitly declare all copy/move constructors and assignments as deleted.
120 #define DISALLOW_COPY_AND_MOVE_AND_ASSIGN(TypeName) \
121  TypeName(TypeName&&) = delete; \
122  TypeName& operator=(TypeName&&) = delete; \
123  DISALLOW_COPY_AND_ASSIGN(TypeName)
124 
125 // Explicitly declare all implicit constructors as deleted, namely the
126 // default constructor, copy constructor and operator= functions.
127 // This is especially useful for classes containing only static methods.
128 #define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \
129  TypeName() = delete; \
130  DISALLOW_COPY_AND_ASSIGN(TypeName)
131 
132 // Disallow copying a type, but provide default construction, move construction
133 // and move assignment. Especially useful for move-only structs.
134 #define MOVE_ONLY_WITH_DEFAULT_CONSTRUCTORS(TypeName) \
135  TypeName() = default; \
136  MOVE_ONLY_NO_DEFAULT_CONSTRUCTOR(TypeName)
137 
138 // Disallow copying a type, and only provide move construction and move
139 // assignment. Especially useful for move-only structs.
140 #define MOVE_ONLY_NO_DEFAULT_CONSTRUCTOR(TypeName) \
141  TypeName(TypeName&&) V8_NOEXCEPT = default; \
142  TypeName& operator=(TypeName&&) V8_NOEXCEPT = default; \
143  DISALLOW_COPY_AND_ASSIGN(TypeName)
144 
145 // A macro to disallow the dynamic allocation.
146 // This should be used in the private: declarations for a class
147 // Declaring operator new and delete as deleted is not spec compliant.
148 // Extract from 3.2.2 of C++11 spec:
149 // [...] A non-placement deallocation function for a class is
150 // odr-used by the definition of the destructor of that class, [...]
151 #define DISALLOW_NEW_AND_DELETE() \
152  void* operator new(size_t) { base::OS::Abort(); } \
153  void* operator new[](size_t) { base::OS::Abort(); }; \
154  void operator delete(void*, size_t) { base::OS::Abort(); } \
155  void operator delete[](void*, size_t) { base::OS::Abort(); }
156 
157 // Define V8_USE_ADDRESS_SANITIZER macro.
158 #if defined(__has_feature)
159 #if __has_feature(address_sanitizer)
160 #define V8_USE_ADDRESS_SANITIZER 1
161 #endif
162 #endif
163 
164 // Define DISABLE_ASAN macro.
165 #ifdef V8_USE_ADDRESS_SANITIZER
166 #define DISABLE_ASAN __attribute__((no_sanitize_address))
167 #else
168 #define DISABLE_ASAN
169 #endif
170 
171 // Define V8_USE_MEMORY_SANITIZER macro.
172 #if defined(__has_feature)
173 #if __has_feature(memory_sanitizer)
174 #define V8_USE_MEMORY_SANITIZER 1
175 #endif
176 #endif
177 
178 // Helper macro to define no_sanitize attributes only with clang.
179 #if defined(__clang__) && defined(__has_attribute)
180 #if __has_attribute(no_sanitize)
181 #define CLANG_NO_SANITIZE(what) __attribute__((no_sanitize(what)))
182 #endif
183 #endif
184 #if !defined(CLANG_NO_SANITIZE)
185 #define CLANG_NO_SANITIZE(what)
186 #endif
187 
188 // DISABLE_CFI_PERF -- Disable Control Flow Integrity checks for Perf reasons.
189 #define DISABLE_CFI_PERF CLANG_NO_SANITIZE("cfi")
190 
191 // DISABLE_CFI_ICALL -- Disable Control Flow Integrity indirect call checks,
192 // useful because calls into JITed code can not be CFI verified.
193 #define DISABLE_CFI_ICALL CLANG_NO_SANITIZE("cfi-icall")
194 
195 #if V8_CC_GNU
196 #define V8_IMMEDIATE_CRASH() __builtin_trap()
197 #else
198 #define V8_IMMEDIATE_CRASH() ((void(*)())0)()
199 #endif
200 
201 // A convenience wrapper around static_assert without a string message argument.
202 // Once C++17 becomes the default, this macro can be removed in favor of the
203 // new static_assert(condition) overload.
204 #define STATIC_ASSERT(test) static_assert(test, #test)
205 
206 namespace v8 {
207 namespace base {
208 
209 // Note that some implementations of std::is_trivially_copyable mandate that at
210 // least one of the copy constructor, move constructor, copy assignment or move
211 // assignment is non-deleted, while others do not. Be aware that also
212 // base::is_trivially_copyable will differ for these cases.
213 template <typename T>
215 #if V8_CC_MSVC
216  // Unfortunately, MSVC 2015 is broken in that std::is_trivially_copyable can
217  // be false even though it should be true according to the standard.
218  // (status at 2018-02-26, observed on the msvc waterfall bot).
219  // Interestingly, the lower-level primitives used below are working as
220  // intended, so we reimplement this according to the standard.
221  // See also https://developercommunity.visualstudio.com/content/problem/
222  // 170883/msvc-type-traits-stdis-trivial-is-bugged.html.
223  static constexpr bool value =
224  // Copy constructor is trivial or deleted.
225  (std::is_trivially_copy_constructible<T>::value ||
226  !std::is_copy_constructible<T>::value) &&
227  // Copy assignment operator is trivial or deleted.
228  (std::is_trivially_copy_assignable<T>::value ||
229  !std::is_copy_assignable<T>::value) &&
230  // Move constructor is trivial or deleted.
231  (std::is_trivially_move_constructible<T>::value ||
232  !std::is_move_constructible<T>::value) &&
233  // Move assignment operator is trivial or deleted.
234  (std::is_trivially_move_assignable<T>::value ||
235  !std::is_move_assignable<T>::value) &&
236  // (Some implementations mandate that one of the above is non-deleted, but
237  // the standard does not, so let's skip this check.)
238  // Trivial non-deleted destructor.
239  std::is_trivially_destructible<T>::value;
240 
241 #elif defined(__GNUC__) && __GNUC__ < 5
242  // WARNING:
243  // On older libstdc++ versions, there is no way to correctly implement
244  // is_trivially_copyable. The workaround below is an approximation (neither
245  // over- nor underapproximation). E.g. it wrongly returns true if the move
246  // constructor is non-trivial, and it wrongly returns false if the copy
247  // constructor is deleted, but copy assignment is trivial.
248  // TODO(rongjie) Remove this workaround once we require gcc >= 5.0
249  static constexpr bool value =
250  __has_trivial_copy(T) && __has_trivial_destructor(T);
251 
252 #else
253  static constexpr bool value = std::is_trivially_copyable<T>::value;
254 #endif
255 };
256 #if defined(__GNUC__) && __GNUC__ < 5
257 // On older libstdc++ versions, base::is_trivially_copyable<T>::value is only an
258 // approximation (see above), so make ASSERT_{NOT_,}TRIVIALLY_COPYABLE a noop.
259 #define ASSERT_TRIVIALLY_COPYABLE(T) static_assert(true, "check disabled")
260 #define ASSERT_NOT_TRIVIALLY_COPYABLE(T) static_assert(true, "check disabled")
261 #else
262 #define ASSERT_TRIVIALLY_COPYABLE(T) \
263  static_assert(::v8::base::is_trivially_copyable<T>::value, \
264  #T " should be trivially copyable")
265 #define ASSERT_NOT_TRIVIALLY_COPYABLE(T) \
266  static_assert(!::v8::base::is_trivially_copyable<T>::value, \
267  #T " should not be trivially copyable")
268 #endif
269 
270 // The USE(x, ...) template is used to silence C++ compiler warnings
271 // issued for (yet) unused variables (typically parameters).
272 // The arguments are guaranteed to be evaluated from left to right.
273 struct Use {
274  template <typename T>
275  Use(T&&) {} // NOLINT(runtime/explicit)
276 };
277 #define USE(...) \
278  do { \
279  ::v8::base::Use unused_tmp_array_for_use_macro[]{__VA_ARGS__}; \
280  (void)unused_tmp_array_for_use_macro; \
281  } while (false)
282 
283 // Evaluate the instantiations of an expression with parameter packs.
284 // Since USE has left-to-right evaluation order of it's arguments,
285 // the parameter pack is iterated from left to right and side effects
286 // have defined behavior.
287 #define ITERATE_PACK(...) USE(0, ((__VA_ARGS__), 0)...)
288 
289 } // namespace base
290 } // namespace v8
291 
292 // implicit_cast<A>(x) triggers an implicit cast from {x} to type {A}. This is
293 // useful in situations where static_cast<A>(x) would do too much.
294 // Only use this for cheap-to-copy types, or use move semantics explicitly.
295 template <class A>
296 V8_INLINE A implicit_cast(A x) {
297  return x;
298 }
299 
300 // Define our own macros for writing 64-bit constants. This is less fragile
301 // than defining __STDC_CONSTANT_MACROS before including <stdint.h>, and it
302 // works on compilers that don't have it (like MSVC).
303 #if V8_CC_MSVC
304 # if V8_HOST_ARCH_64_BIT
305 # define V8_PTR_PREFIX "ll"
306 # else
307 # define V8_PTR_PREFIX ""
308 # endif // V8_HOST_ARCH_64_BIT
309 #elif V8_CC_MINGW64
310 # define V8_PTR_PREFIX "I64"
311 #elif V8_HOST_ARCH_64_BIT
312 # define V8_PTR_PREFIX "l"
313 #else
314 #if V8_OS_AIX
315 #define V8_PTR_PREFIX "l"
316 #else
317 # define V8_PTR_PREFIX ""
318 #endif
319 #endif
320 
321 #define V8PRIxPTR V8_PTR_PREFIX "x"
322 #define V8PRIdPTR V8_PTR_PREFIX "d"
323 #define V8PRIuPTR V8_PTR_PREFIX "u"
324 
325 #ifdef V8_TARGET_ARCH_64_BIT
326 #define V8_PTR_HEX_DIGITS 12
327 #define V8PRIxPTR_FMT "0x%012" V8PRIxPTR
328 #else
329 #define V8_PTR_HEX_DIGITS 8
330 #define V8PRIxPTR_FMT "0x%08" V8PRIxPTR
331 #endif
332 
333 // ptrdiff_t is 't' according to the standard, but MSVC uses 'I'.
334 #if V8_CC_MSVC
335 #define V8PRIxPTRDIFF "Ix"
336 #define V8PRIdPTRDIFF "Id"
337 #define V8PRIuPTRDIFF "Iu"
338 #else
339 #define V8PRIxPTRDIFF "tx"
340 #define V8PRIdPTRDIFF "td"
341 #define V8PRIuPTRDIFF "tu"
342 #endif
343 
344 // Fix for Mac OS X defining uintptr_t as "unsigned long":
345 #if V8_OS_MACOSX
346 #undef V8PRIxPTR
347 #define V8PRIxPTR "lx"
348 #undef V8PRIdPTR
349 #define V8PRIdPTR "ld"
350 #undef V8PRIuPTR
351 #define V8PRIuPTR "lxu"
352 #endif
353 
354 // The following macro works on both 32 and 64-bit platforms.
355 // Usage: instead of writing 0x1234567890123456
356 // write V8_2PART_UINT64_C(0x12345678,90123456);
357 #define V8_2PART_UINT64_C(a, b) (((static_cast<uint64_t>(a) << 32) + 0x##b##u))
358 
359 // Return the largest multiple of m which is <= x.
360 template <typename T>
361 inline T RoundDown(T x, intptr_t m) {
362  STATIC_ASSERT(std::is_integral<T>::value);
363  // m must be a power of two.
364  DCHECK(m != 0 && ((m & (m - 1)) == 0));
365  return x & -m;
366 }
367 template <intptr_t m, typename T>
368 constexpr inline T RoundDown(T x) {
369  STATIC_ASSERT(std::is_integral<T>::value);
370  // m must be a power of two.
371  STATIC_ASSERT(m != 0 && ((m & (m - 1)) == 0));
372  return x & -m;
373 }
374 
375 // Return the smallest multiple of m which is >= x.
376 template <typename T>
377 inline T RoundUp(T x, intptr_t m) {
378  STATIC_ASSERT(std::is_integral<T>::value);
379  return RoundDown<T>(static_cast<T>(x + m - 1), m);
380 }
381 template <intptr_t m, typename T>
382 constexpr inline T RoundUp(T x) {
383  STATIC_ASSERT(std::is_integral<T>::value);
384  return RoundDown<m, T>(static_cast<T>(x + (m - 1)));
385 }
386 
387 template <typename T, typename U>
388 constexpr inline bool IsAligned(T value, U alignment) {
389  return (value & (alignment - 1)) == 0;
390 }
391 
392 inline void* AlignedAddress(void* address, size_t alignment) {
393  // The alignment must be a power of two.
394  DCHECK_EQ(alignment & (alignment - 1), 0u);
395  return reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(address) &
396  ~static_cast<uintptr_t>(alignment - 1));
397 }
398 
399 // Bounds checks for float to integer conversions, which does truncation. Hence,
400 // the range of legal values is (min - 1, max + 1).
401 template <typename int_t, typename float_t, typename biggest_int_t = int64_t>
402 bool is_inbounds(float_t v) {
403  static_assert(sizeof(int_t) < sizeof(biggest_int_t),
404  "int_t can't be bounds checked by the compiler");
405  constexpr float_t kLowerBound =
406  static_cast<float_t>(std::numeric_limits<int_t>::min()) - 1;
407  constexpr float_t kUpperBound =
408  static_cast<float_t>(std::numeric_limits<int_t>::max()) + 1;
409  constexpr bool kLowerBoundIsMin =
410  static_cast<biggest_int_t>(kLowerBound) ==
411  static_cast<biggest_int_t>(std::numeric_limits<int_t>::min());
412  constexpr bool kUpperBoundIsMax =
413  static_cast<biggest_int_t>(kUpperBound) ==
414  static_cast<biggest_int_t>(std::numeric_limits<int_t>::max());
415  return (kLowerBoundIsMin ? (kLowerBound <= v) : (kLowerBound < v)) &&
416  (kUpperBoundIsMax ? (v <= kUpperBound) : (v < kUpperBound));
417 }
418 
419 #ifdef V8_OS_WIN
420 
421 // Setup for Windows shared library export.
422 #ifdef BUILDING_V8_SHARED
423 #define V8_EXPORT_PRIVATE __declspec(dllexport)
424 #elif USING_V8_SHARED
425 #define V8_EXPORT_PRIVATE __declspec(dllimport)
426 #else
427 #define V8_EXPORT_PRIVATE
428 #endif // BUILDING_V8_SHARED
429 
430 #else // V8_OS_WIN
431 
432 // Setup for Linux shared library export.
433 #if V8_HAS_ATTRIBUTE_VISIBILITY
434 #ifdef BUILDING_V8_SHARED
435 #define V8_EXPORT_PRIVATE __attribute__((visibility("default")))
436 #else
437 #define V8_EXPORT_PRIVATE
438 #endif
439 #else
440 #define V8_EXPORT_PRIVATE
441 #endif
442 
443 #endif // V8_OS_WIN
444 
445 #endif // V8_BASE_MACROS_H_
Definition: libplatform.h:13