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 |