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 <stddef.h>
9#include <stdint.h>
10
11#include <cstring>
12
13#include "src/base/build_config.h"
14#include "src/base/compiler-specific.h"
15#include "src/base/logging.h"
16
17
18// TODO(all) Replace all uses of this macro with C++'s offsetof. To do that, we
19// have to make sure that only standard-layout types and simple field
20// designators are used.
21#define OFFSET_OF(type, field) \
22  (reinterpret_cast<intptr_t>(&(reinterpret_cast<type*>(16)->field)) - 16)
23
24
25#if V8_OS_NACL
26
27// ARRAYSIZE_UNSAFE performs essentially the same calculation as arraysize,
28// but can be used on anonymous types or types defined inside
29// functions.  It's less safe than arraysize as it accepts some
30// (although not all) pointers.  Therefore, you should use arraysize
31// whenever possible.
32//
33// The expression ARRAYSIZE_UNSAFE(a) is a compile-time constant of type
34// size_t.
35//
36// ARRAYSIZE_UNSAFE catches a few type errors.  If you see a compiler error
37//
38//   "warning: division by zero in ..."
39//
40// when using ARRAYSIZE_UNSAFE, you are (wrongfully) giving it a pointer.
41// You should only use ARRAYSIZE_UNSAFE on statically allocated arrays.
42//
43// The following comments are on the implementation details, and can
44// be ignored by the users.
45//
46// ARRAYSIZE_UNSAFE(arr) works by inspecting sizeof(arr) (the # of bytes in
47// the array) and sizeof(*(arr)) (the # of bytes in one array
48// element).  If the former is divisible by the latter, perhaps arr is
49// indeed an array, in which case the division result is the # of
50// elements in the array.  Otherwise, arr cannot possibly be an array,
51// and we generate a compiler error to prevent the code from
52// compiling.
53//
54// Since the size of bool is implementation-defined, we need to cast
55// !(sizeof(a) & sizeof(*(a))) to size_t in order to ensure the final
56// result has type size_t.
57//
58// This macro is not perfect as it wrongfully accepts certain
59// pointers, namely where the pointer size is divisible by the pointee
60// size.  Since all our code has to go through a 32-bit compiler,
61// where a pointer is 4 bytes, this means all pointers to a type whose
62// size is 3 or greater than 4 will be (righteously) rejected.
63#define ARRAYSIZE_UNSAFE(a)     \
64  ((sizeof(a) / sizeof(*(a))) / \
65   static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))  // NOLINT
66
67// TODO(bmeurer): For some reason, the NaCl toolchain cannot handle the correct
68// definition of arraysize() below, so we have to use the unsafe version for
69// now.
70#define arraysize ARRAYSIZE_UNSAFE
71
72#else  // V8_OS_NACL
73
74// The arraysize(arr) macro returns the # of elements in an array arr.
75// The expression is a compile-time constant, and therefore can be
76// used in defining new arrays, for example.  If you use arraysize on
77// a pointer by mistake, you will get a compile-time error.
78//
79// One caveat is that arraysize() doesn't accept any array of an
80// anonymous type or a type defined inside a function.  In these rare
81// cases, you have to use the unsafe ARRAYSIZE_UNSAFE() macro below.  This is
82// due to a limitation in C++'s template system.  The limitation might
83// eventually be removed, but it hasn't happened yet.
84#define arraysize(array) (sizeof(ArraySizeHelper(array)))
85
86
87// This template function declaration is used in defining arraysize.
88// Note that the function doesn't need an implementation, as we only
89// use its type.
90template <typename T, size_t N>
91char (&ArraySizeHelper(T (&array)[N]))[N];
92
93
94#if !V8_CC_MSVC
95// That gcc wants both of these prototypes seems mysterious. VC, for
96// its part, can't decide which to use (another mystery). Matching of
97// template overloads: the final frontier.
98template <typename T, size_t N>
99char (&ArraySizeHelper(const T (&array)[N]))[N];
100#endif
101
102#endif  // V8_OS_NACL
103
104
105// bit_cast<Dest,Source> is a template function that implements the
106// equivalent of "*reinterpret_cast<Dest*>(&source)".  We need this in
107// very low-level functions like the protobuf library and fast math
108// support.
109//
110//   float f = 3.14159265358979;
111//   int i = bit_cast<int32>(f);
112//   // i = 0x40490fdb
113//
114// The classical address-casting method is:
115//
116//   // WRONG
117//   float f = 3.14159265358979;            // WRONG
118//   int i = * reinterpret_cast<int*>(&f);  // WRONG
119//
120// The address-casting method actually produces undefined behavior
121// according to ISO C++ specification section 3.10 -15 -.  Roughly, this
122// section says: if an object in memory has one type, and a program
123// accesses it with a different type, then the result is undefined
124// behavior for most values of "different type".
125//
126// This is true for any cast syntax, either *(int*)&f or
127// *reinterpret_cast<int*>(&f).  And it is particularly true for
128// conversions between integral lvalues and floating-point lvalues.
129//
130// The purpose of 3.10 -15- is to allow optimizing compilers to assume
131// that expressions with different types refer to different memory.  gcc
132// 4.0.1 has an optimizer that takes advantage of this.  So a
133// non-conforming program quietly produces wildly incorrect output.
134//
135// The problem is not the use of reinterpret_cast.  The problem is type
136// punning: holding an object in memory of one type and reading its bits
137// back using a different type.
138//
139// The C++ standard is more subtle and complex than this, but that
140// is the basic idea.
141//
142// Anyways ...
143//
144// bit_cast<> calls memcpy() which is blessed by the standard,
145// especially by the example in section 3.9 .  Also, of course,
146// bit_cast<> wraps up the nasty logic in one place.
147//
148// Fortunately memcpy() is very fast.  In optimized mode, with a
149// constant size, gcc 2.95.3, gcc 4.0.1, and msvc 7.1 produce inline
150// code with the minimal amount of data movement.  On a 32-bit system,
151// memcpy(d,s,4) compiles to one load and one store, and memcpy(d,s,8)
152// compiles to two loads and two stores.
153//
154// I tested this code with gcc 2.95.3, gcc 4.0.1, icc 8.1, and msvc 7.1.
155//
156// WARNING: if Dest or Source is a non-POD type, the result of the memcpy
157// is likely to surprise you.
158template <class Dest, class Source>
159V8_INLINE Dest bit_cast(Source const& source) {
160  static_assert(sizeof(Dest) == sizeof(Source),
161                "source and dest must be same size");
162  Dest dest;
163  memcpy(&dest, &source, sizeof(dest));
164  return dest;
165}
166
167
168// Put this in the private: declarations for a class to be unassignable.
169#define DISALLOW_ASSIGN(TypeName) void operator=(const TypeName&)
170
171
172// A macro to disallow the evil copy constructor and operator= functions
173// This should be used in the private: declarations for a class
174#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
175  TypeName(const TypeName&) = delete;      \
176  void operator=(const TypeName&) = delete
177
178
179// A macro to disallow all the implicit constructors, namely the
180// default constructor, copy constructor and operator= functions.
181//
182// This should be used in the private: declarations for a class
183// that wants to prevent anyone from instantiating it. This is
184// especially useful for classes containing only static methods.
185#define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \
186  TypeName() = delete;                           \
187  DISALLOW_COPY_AND_ASSIGN(TypeName)
188
189
190// Newly written code should use V8_INLINE and V8_NOINLINE directly.
191#define INLINE(declarator)    V8_INLINE declarator
192#define NO_INLINE(declarator) V8_NOINLINE declarator
193
194
195// Newly written code should use WARN_UNUSED_RESULT.
196#define MUST_USE_RESULT WARN_UNUSED_RESULT
197
198
199// Define V8_USE_ADDRESS_SANITIZER macros.
200#if defined(__has_feature)
201#if __has_feature(address_sanitizer)
202#define V8_USE_ADDRESS_SANITIZER 1
203#endif
204#endif
205
206// Define DISABLE_ASAN macros.
207#ifdef V8_USE_ADDRESS_SANITIZER
208#define DISABLE_ASAN __attribute__((no_sanitize_address))
209#else
210#define DISABLE_ASAN
211#endif
212
213
214#if V8_CC_GNU
215#define V8_IMMEDIATE_CRASH() __builtin_trap()
216#else
217#define V8_IMMEDIATE_CRASH() ((void(*)())0)()
218#endif
219
220
221// TODO(all) Replace all uses of this macro with static_assert, remove macro.
222#define STATIC_ASSERT(test) static_assert(test, #test)
223
224
225// The USE(x) template is used to silence C++ compiler warnings
226// issued for (yet) unused variables (typically parameters).
227template <typename T>
228inline void USE(T) { }
229
230
231#define IS_POWER_OF_TWO(x) ((x) != 0 && (((x) & ((x) - 1)) == 0))
232
233
234// Define our own macros for writing 64-bit constants.  This is less fragile
235// than defining __STDC_CONSTANT_MACROS before including <stdint.h>, and it
236// works on compilers that don't have it (like MSVC).
237#if V8_CC_MSVC
238# define V8_UINT64_C(x)   (x ## UI64)
239# define V8_INT64_C(x)    (x ## I64)
240# if V8_HOST_ARCH_64_BIT
241#  define V8_INTPTR_C(x)  (x ## I64)
242#  define V8_PTR_PREFIX   "ll"
243# else
244#  define V8_INTPTR_C(x)  (x)
245#  define V8_PTR_PREFIX   ""
246# endif  // V8_HOST_ARCH_64_BIT
247#elif V8_CC_MINGW64
248# define V8_UINT64_C(x)   (x ## ULL)
249# define V8_INT64_C(x)    (x ## LL)
250# define V8_INTPTR_C(x)   (x ## LL)
251# define V8_PTR_PREFIX    "I64"
252#elif V8_HOST_ARCH_64_BIT
253# if V8_OS_MACOSX || V8_OS_OPENBSD
254#  define V8_UINT64_C(x)   (x ## ULL)
255#  define V8_INT64_C(x)    (x ## LL)
256# else
257#  define V8_UINT64_C(x)   (x ## UL)
258#  define V8_INT64_C(x)    (x ## L)
259# endif
260# define V8_INTPTR_C(x)   (x ## L)
261# define V8_PTR_PREFIX    "l"
262#else
263# define V8_UINT64_C(x)   (x ## ULL)
264# define V8_INT64_C(x)    (x ## LL)
265# define V8_INTPTR_C(x)   (x)
266#if V8_OS_AIX
267#define V8_PTR_PREFIX "l"
268#else
269# define V8_PTR_PREFIX    ""
270#endif
271#endif
272
273#define V8PRIxPTR V8_PTR_PREFIX "x"
274#define V8PRIdPTR V8_PTR_PREFIX "d"
275#define V8PRIuPTR V8_PTR_PREFIX "u"
276
277// Fix for Mac OS X defining uintptr_t as "unsigned long":
278#if V8_OS_MACOSX
279#undef V8PRIxPTR
280#define V8PRIxPTR "lx"
281#endif
282
283// The following macro works on both 32 and 64-bit platforms.
284// Usage: instead of writing 0x1234567890123456
285//      write V8_2PART_UINT64_C(0x12345678,90123456);
286#define V8_2PART_UINT64_C(a, b) (((static_cast<uint64_t>(a) << 32) + 0x##b##u))
287
288
289// Compute the 0-relative offset of some absolute value x of type T.
290// This allows conversion of Addresses and integral types into
291// 0-relative int offsets.
292template <typename T>
293inline intptr_t OffsetFrom(T x) {
294  return x - static_cast<T>(0);
295}
296
297
298// Compute the absolute value of type T for some 0-relative offset x.
299// This allows conversion of 0-relative int offsets into Addresses and
300// integral types.
301template <typename T>
302inline T AddressFrom(intptr_t x) {
303  return static_cast<T>(static_cast<T>(0) + x);
304}
305
306
307// Return the largest multiple of m which is <= x.
308template <typename T>
309inline T RoundDown(T x, intptr_t m) {
310  DCHECK(IS_POWER_OF_TWO(m));
311  return AddressFrom<T>(OffsetFrom(x) & -m);
312}
313
314
315// Return the smallest multiple of m which is >= x.
316template <typename T>
317inline T RoundUp(T x, intptr_t m) {
318  return RoundDown<T>(static_cast<T>(x + m - 1), m);
319}
320
321
322namespace v8 {
323namespace base {
324
325// TODO(yangguo): This is a poor man's replacement for std::is_fundamental,
326// which requires C++11. Switch to std::is_fundamental once possible.
327template <typename T>
328inline bool is_fundamental() {
329  return false;
330}
331
332template <>
333inline bool is_fundamental<uint8_t>() {
334  return true;
335}
336
337}  // namespace base
338}  // namespace v8
339
340#endif   // V8_BASE_MACROS_H_
341