| OLD | NEW | 
|---|
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #ifndef V8_BASE_MACROS_H_ | 5 #ifndef V8_BASE_MACROS_H_ | 
| 6 #define V8_BASE_MACROS_H_ | 6 #define V8_BASE_MACROS_H_ | 
| 7 | 7 | 
| 8 #include "src/base/compiler-specific.h" | 8 #include "src/base/compiler-specific.h" | 
| 9 #include "src/base/format-macros.h" | 9 #include "src/base/format-macros.h" | 
| 10 #include "src/base/logging.h" | 10 #include "src/base/logging.h" | 
| 11 | 11 | 
| 12 | 12 | 
| 13 // TODO(all) Replace all uses of this macro with C++'s offsetof. To do that, we | 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 | 14 // have to make sure that only standard-layout types and simple field | 
| 15 // designators are used. | 15 // designators are used. | 
| 16 #define OFFSET_OF(type, field) \ | 16 #define OFFSET_OF(type, field) \ | 
| 17   (reinterpret_cast<intptr_t>(&(reinterpret_cast<type*>(16)->field)) - 16) | 17   (reinterpret_cast<intptr_t>(&(reinterpret_cast<type*>(16)->field)) - 16) | 
| 18 | 18 | 
| 19 | 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. | 20 // The arraysize(arr) macro returns the # of elements in an array arr. | 
| 70 // The expression is a compile-time constant, and therefore can be | 21 // The expression is a compile-time constant, and therefore can be | 
| 71 // used in defining new arrays, for example.  If you use arraysize on | 22 // used in defining new arrays, for example.  If you use arraysize on | 
| 72 // a pointer by mistake, you will get a compile-time error. | 23 // a pointer by mistake, you will get a compile-time error. | 
| 73 // | 24 // | 
| 74 // One caveat is that arraysize() doesn't accept any array of an | 25 // 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 | 26 // 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 | 27 // 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 | 28 // due to a limitation in C++'s template system.  The limitation might | 
| 78 // eventually be removed, but it hasn't happened yet. | 29 // eventually be removed, but it hasn't happened yet. | 
| 79 #define arraysize(array) (sizeof(ArraySizeHelper(array))) | 30 #define arraysize(array) (sizeof(ArraySizeHelper(array))) | 
| 80 | 31 | 
| 81 | 32 | 
| 82 // This template function declaration is used in defining arraysize. | 33 // This template function declaration is used in defining arraysize. | 
| 83 // Note that the function doesn't need an implementation, as we only | 34 // Note that the function doesn't need an implementation, as we only | 
| 84 // use its type. | 35 // use its type. | 
| 85 template <typename T, size_t N> | 36 template <typename T, size_t N> | 
| 86 char (&ArraySizeHelper(T (&array)[N]))[N]; | 37 char (&ArraySizeHelper(T (&array)[N]))[N]; | 
| 87 | 38 | 
| 88 | 39 | 
| 89 #if !V8_CC_MSVC | 40 #if !V8_CC_MSVC | 
| 90 // That gcc wants both of these prototypes seems mysterious. VC, for | 41 // That gcc wants both of these prototypes seems mysterious. VC, for | 
| 91 // its part, can't decide which to use (another mystery). Matching of | 42 // its part, can't decide which to use (another mystery). Matching of | 
| 92 // template overloads: the final frontier. | 43 // template overloads: the final frontier. | 
| 93 template <typename T, size_t N> | 44 template <typename T, size_t N> | 
| 94 char (&ArraySizeHelper(const T (&array)[N]))[N]; | 45 char (&ArraySizeHelper(const T (&array)[N]))[N]; | 
| 95 #endif | 46 #endif | 
| 96 | 47 | 
| 97 #endif  // V8_OS_NACL |  | 
| 98 |  | 
| 99 | 48 | 
| 100 // bit_cast<Dest,Source> is a template function that implements the | 49 // bit_cast<Dest,Source> is a template function that implements the | 
| 101 // equivalent of "*reinterpret_cast<Dest*>(&source)".  We need this in | 50 // equivalent of "*reinterpret_cast<Dest*>(&source)".  We need this in | 
| 102 // very low-level functions like the protobuf library and fast math | 51 // very low-level functions like the protobuf library and fast math | 
| 103 // support. | 52 // support. | 
| 104 // | 53 // | 
| 105 //   float f = 3.14159265358979; | 54 //   float f = 3.14159265358979; | 
| 106 //   int i = bit_cast<int32>(f); | 55 //   int i = bit_cast<int32>(f); | 
| 107 //   // i = 0x40490fdb | 56 //   // i = 0x40490fdb | 
| 108 // | 57 // | 
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 341 | 290 | 
| 342 template <> | 291 template <> | 
| 343 inline bool is_fundamental<uint8_t>() { | 292 inline bool is_fundamental<uint8_t>() { | 
| 344   return true; | 293   return true; | 
| 345 } | 294 } | 
| 346 | 295 | 
| 347 }  // namespace base | 296 }  // namespace base | 
| 348 }  // namespace v8 | 297 }  // namespace v8 | 
| 349 | 298 | 
| 350 #endif   // V8_BASE_MACROS_H_ | 299 #endif   // V8_BASE_MACROS_H_ | 
| OLD | NEW | 
|---|