Chromium Code Reviews| 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 "include/v8stdint.h" | 8 #include "include/v8stdint.h" |
| 9 #include "src/base/build_config.h" | 9 #include "src/base/build_config.h" |
| 10 #include "src/base/logging.h" | 10 #include "src/base/logging.h" |
| 11 | 11 |
| 12 | 12 |
| 13 // The expression OFFSET_OF(type, field) computes the byte-offset | 13 // The expression OFFSET_OF(type, field) computes the byte-offset |
| 14 // of the specified field relative to the containing type. This | 14 // of the specified field relative to the containing type. This |
| 15 // corresponds to 'offsetof' (in stddef.h), except that it doesn't | 15 // corresponds to 'offsetof' (in stddef.h), except that it doesn't |
| 16 // use 0 or NULL, which causes a problem with the compiler warnings | 16 // use 0 or NULL, which causes a problem with the compiler warnings |
| 17 // we have enabled (which is also why 'offsetof' doesn't seem to work). | 17 // we have enabled (which is also why 'offsetof' doesn't seem to work). |
| 18 // Here we simply use the non-zero value 4, which seems to work. | 18 // Here we simply use the non-zero value 4, which seems to work. |
| 19 #define OFFSET_OF(type, field) \ | 19 #define OFFSET_OF(type, field) \ |
| 20 (reinterpret_cast<intptr_t>(&(reinterpret_cast<type*>(4)->field)) - 4) | 20 (reinterpret_cast<intptr_t>(&(reinterpret_cast<type*>(4)->field)) - 4) |
| 21 | 21 |
| 22 | 22 |
| 23 // The expression ARRAY_SIZE(a) is a compile-time constant of type | 23 // The arraysize(arr) macro returns the # of elements in an array arr. |
| 24 // size_t which represents the number of elements of the given | 24 // The expression is a compile-time constant, and therefore can be |
| 25 // array. You should only use ARRAY_SIZE on statically allocated | 25 // used in defining new arrays, for example. If you use arraysize on |
| 26 // arrays. | 26 // a pointer by mistake, you will get a compile-time error. |
| 27 #define ARRAY_SIZE(a) \ | 27 // |
| 28 ((sizeof(a) / sizeof(*(a))) / \ | 28 // One caveat is that arraysize() doesn't accept any array of an |
| 29 static_cast<size_t>(!(sizeof(a) % sizeof(*(a))))) | 29 // anonymous type or a type defined inside a function. In these rare |
| 30 // cases, you have to use the unsafe ARRAYSIZE_UNSAFE() macro below. This is | |
| 31 // due to a limitation in C++'s template system. The limitation might | |
| 32 // eventually be removed, but it hasn't happened yet. | |
| 33 #define arraysize(array) (sizeof(ArraySizeHelper(array))) | |
| 34 | |
| 35 | |
| 36 // This template function declaration is used in defining arraysize. | |
| 37 // Note that the function doesn't need an implementation, as we only | |
| 38 // use its type. | |
| 39 template <typename T, size_t N> | |
| 40 char (&ArraySizeHelper(T (&array)[N]))[N]; | |
| 41 | |
| 42 | |
| 43 #if V8_CC_GNU | |
| 44 // That gcc wants both of these prototypes seems mysterious. VC, for | |
| 45 // its part, can't decide which to use (another mystery). Matching of | |
| 46 // template overloads: the final frontier. | |
| 47 template <typename T, size_t N> | |
| 48 char (&ArraySizeHelper(const T (&array)[N]))[N]; | |
| 49 #endif | |
| 50 | |
| 51 | |
| 52 // ARRAYSIZE_UNSAFE performs essentially the same calculation as arraysize, | |
| 53 // but can be used on anonymous types or types defined inside | |
| 54 // functions. It's less safe than arraysize as it accepts some | |
| 55 // (although not all) pointers. Therefore, you should use arraysize | |
| 56 // whenever possible. | |
| 57 // | |
| 58 // The expression ARRAYSIZE_UNSAFE(a) is a compile-time constant of type | |
| 59 // size_t. | |
| 60 // | |
| 61 // ARRAYSIZE_UNSAFE catches a few type errors. If you see a compiler error | |
| 62 // | |
| 63 // "warning: division by zero in ..." | |
| 64 // | |
| 65 // when using ARRAYSIZE_UNSAFE, you are (wrongfully) giving it a pointer. | |
| 66 // You should only use ARRAYSIZE_UNSAFE on statically allocated arrays. | |
| 67 // | |
| 68 // The following comments are on the implementation details, and can | |
| 69 // be ignored by the users. | |
| 70 // | |
| 71 // ARRAYSIZE_UNSAFE(arr) works by inspecting sizeof(arr) (the # of bytes in | |
| 72 // the array) and sizeof(*(arr)) (the # of bytes in one array | |
| 73 // element). If the former is divisible by the latter, perhaps arr is | |
| 74 // indeed an array, in which case the division result is the # of | |
| 75 // elements in the array. Otherwise, arr cannot possibly be an array, | |
| 76 // and we generate a compiler error to prevent the code from | |
| 77 // compiling. | |
| 78 // | |
| 79 // Since the size of bool is implementation-defined, we need to cast | |
| 80 // !(sizeof(a) & sizeof(*(a))) to size_t in order to ensure the final | |
| 81 // result has type size_t. | |
| 82 // | |
| 83 // This macro is not perfect as it wrongfully accepts certain | |
| 84 // pointers, namely where the pointer size is divisible by the pointee | |
| 85 // size. Since all our code has to go through a 32-bit compiler, | |
| 86 // where a pointer is 4 bytes, this means all pointers to a type whose | |
| 87 // size is 3 or greater than 4 will be (righteously) rejected. | |
| 88 #define ARRAYSIZE_UNSAFE(a) \ | |
|
Yang
2014/08/26 09:17:22
Do we actually need this?
| |
| 89 ((sizeof(a) / sizeof(*(a))) / \ | |
| 90 static_cast<size_t>(!(sizeof(a) % sizeof(*(a))))) // NOLINT | |
| 30 | 91 |
| 31 | 92 |
| 32 // A macro to disallow the evil copy constructor and operator= functions | 93 // A macro to disallow the evil copy constructor and operator= functions |
| 33 // This should be used in the private: declarations for a class | 94 // This should be used in the private: declarations for a class |
| 34 #define DISALLOW_COPY_AND_ASSIGN(TypeName) \ | 95 #define DISALLOW_COPY_AND_ASSIGN(TypeName) \ |
| 35 TypeName(const TypeName&) V8_DELETE; \ | 96 TypeName(const TypeName&) V8_DELETE; \ |
| 36 void operator=(const TypeName&) V8_DELETE | 97 void operator=(const TypeName&) V8_DELETE |
| 37 | 98 |
| 38 | 99 |
| 39 // A macro to disallow all the implicit constructors, namely the | 100 // A macro to disallow all the implicit constructors, namely the |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 250 // Returns current value of top of the stack. Works correctly with ASAN. | 311 // Returns current value of top of the stack. Works correctly with ASAN. |
| 251 DISABLE_ASAN | 312 DISABLE_ASAN |
| 252 inline uintptr_t GetCurrentStackPosition() { | 313 inline uintptr_t GetCurrentStackPosition() { |
| 253 // Takes the address of the limit variable in order to find out where | 314 // Takes the address of the limit variable in order to find out where |
| 254 // the top of stack is right now. | 315 // the top of stack is right now. |
| 255 uintptr_t limit = reinterpret_cast<uintptr_t>(&limit); | 316 uintptr_t limit = reinterpret_cast<uintptr_t>(&limit); |
| 256 return limit; | 317 return limit; |
| 257 } | 318 } |
| 258 | 319 |
| 259 #endif // V8_BASE_MACROS_H_ | 320 #endif // V8_BASE_MACROS_H_ |
| OLD | NEW |