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.
5 #ifndef V8_BASE_MACROS_H_
6 #define V8_BASE_MACROS_H_
8 #include "include/v8stdint.h"
9 #include "src/base/build_config.h"
12 // The expression OFFSET_OF(type, field) computes the byte-offset
13 // of the specified field relative to the containing type. This
14 // corresponds to 'offsetof' (in stddef.h), except that it doesn't
15 // use 0 or NULL, which causes a problem with the compiler warnings
16 // we have enabled (which is also why 'offsetof' doesn't seem to work).
17 // Here we simply use the non-zero value 4, which seems to work.
18 #define OFFSET_OF(type, field) \
19 (reinterpret_cast<intptr_t>(&(reinterpret_cast<type*>(4)->field)) - 4)
22 // The expression ARRAY_SIZE(a) is a compile-time constant of type
23 // size_t which represents the number of elements of the given
24 // array. You should only use ARRAY_SIZE on statically allocated
26 #define ARRAY_SIZE(a) \
27 ((sizeof(a) / sizeof(*(a))) / \
28 static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))
31 // A macro to disallow the evil copy constructor and operator= functions
32 // This should be used in the private: declarations for a class
33 #define DISALLOW_COPY_AND_ASSIGN(TypeName) \
34 TypeName(const TypeName&) V8_DELETE; \
35 void operator=(const TypeName&) V8_DELETE
38 // A macro to disallow all the implicit constructors, namely the
39 // default constructor, copy constructor and operator= functions.
41 // This should be used in the private: declarations for a class
42 // that wants to prevent anyone from instantiating it. This is
43 // especially useful for classes containing only static methods.
44 #define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \
45 TypeName() V8_DELETE; \
46 DISALLOW_COPY_AND_ASSIGN(TypeName)
49 // Newly written code should use V8_INLINE and V8_NOINLINE directly.
50 #define INLINE(declarator) V8_INLINE declarator
51 #define NO_INLINE(declarator) V8_NOINLINE declarator
54 // Newly written code should use V8_WARN_UNUSED_RESULT.
55 #define MUST_USE_RESULT V8_WARN_UNUSED_RESULT
58 // Define V8_USE_ADDRESS_SANITIZER macros.
59 #if defined(__has_feature)
60 #if __has_feature(address_sanitizer)
61 #define V8_USE_ADDRESS_SANITIZER 1
65 // Define DISABLE_ASAN macros.
66 #ifdef V8_USE_ADDRESS_SANITIZER
67 #define DISABLE_ASAN __attribute__((no_sanitize_address))
74 #define V8_IMMEDIATE_CRASH() __builtin_trap()
76 #define V8_IMMEDIATE_CRASH() ((void(*)())0)()
80 // Use C++11 static_assert if possible, which gives error
81 // messages that are easier to understand on first sight.
82 #if V8_HAS_CXX11_STATIC_ASSERT
83 #define STATIC_ASSERT(test) static_assert(test, #test)
85 // This is inspired by the static assertion facility in boost. This
86 // is pretty magical. If it causes you trouble on a platform you may
87 // find a fix in the boost code.
88 template <bool> class StaticAssertion;
89 template <> class StaticAssertion<true> { };
90 // This macro joins two tokens. If one of the tokens is a macro the
91 // helper call causes it to be resolved before joining.
92 #define SEMI_STATIC_JOIN(a, b) SEMI_STATIC_JOIN_HELPER(a, b)
93 #define SEMI_STATIC_JOIN_HELPER(a, b) a##b
94 // Causes an error during compilation of the condition is not
95 // statically known to be true. It is formulated as a typedef so that
96 // it can be used wherever a typedef can be used. Beware that this
97 // actually causes each use to introduce a new defined type with a
98 // name depending on the source line.
99 template <int> class StaticAssertionHelper { };
100 #define STATIC_ASSERT(test) \
102 StaticAssertionHelper<sizeof(StaticAssertion<static_cast<bool>((test))>)> \
103 SEMI_STATIC_JOIN(__StaticAssertTypedef__, __LINE__) V8_UNUSED
108 // The USE(x) template is used to silence C++ compiler warnings
109 // issued for (yet) unused variables (typically parameters).
110 template <typename T>
111 inline void USE(T) { }
114 #define IS_POWER_OF_TWO(x) ((x) != 0 && (((x) & ((x) - 1)) == 0))
117 // Define our own macros for writing 64-bit constants. This is less fragile
118 // than defining __STDC_CONSTANT_MACROS before including <stdint.h>, and it
119 // works on compilers that don't have it (like MSVC).
121 # define V8_UINT64_C(x) (x ## UI64)
122 # define V8_INT64_C(x) (x ## I64)
123 # if V8_HOST_ARCH_64_BIT
124 # define V8_INTPTR_C(x) (x ## I64)
125 # define V8_PTR_PREFIX "ll"
127 # define V8_INTPTR_C(x) (x)
128 # define V8_PTR_PREFIX ""
129 # endif // V8_HOST_ARCH_64_BIT
131 # define V8_UINT64_C(x) (x ## ULL)
132 # define V8_INT64_C(x) (x ## LL)
133 # define V8_INTPTR_C(x) (x ## LL)
134 # define V8_PTR_PREFIX "I64"
135 #elif V8_HOST_ARCH_64_BIT
137 # define V8_UINT64_C(x) (x ## ULL)
138 # define V8_INT64_C(x) (x ## LL)
140 # define V8_UINT64_C(x) (x ## UL)
141 # define V8_INT64_C(x) (x ## L)
143 # define V8_INTPTR_C(x) (x ## L)
144 # define V8_PTR_PREFIX "l"
146 # define V8_UINT64_C(x) (x ## ULL)
147 # define V8_INT64_C(x) (x ## LL)
148 # define V8_INTPTR_C(x) (x)
149 # define V8_PTR_PREFIX ""
152 #define V8PRIxPTR V8_PTR_PREFIX "x"
153 #define V8PRIdPTR V8_PTR_PREFIX "d"
154 #define V8PRIuPTR V8_PTR_PREFIX "u"
156 // Fix for Mac OS X defining uintptr_t as "unsigned long":
159 #define V8PRIxPTR "lx"
162 // The following macro works on both 32 and 64-bit platforms.
163 // Usage: instead of writing 0x1234567890123456
164 // write V8_2PART_UINT64_C(0x12345678,90123456);
165 #define V8_2PART_UINT64_C(a, b) (((static_cast<uint64_t>(a) << 32) + 0x##b##u))
167 #endif // V8_BASE_MACROS_H_