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