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