| 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 |