1 /* 2 * Copyright (C) 2008 Apple Inc. All Rights Reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 #ifndef WTF_StdLibExtras_h 27 #define WTF_StdLibExtras_h 28 29 #include "wtf/Assertions.h" 30 #include "wtf/CPU.h" 31 #include "wtf/CheckedArithmetic.h" 32 33 // Use this to declare and define a static local variable (static T;) so that 34 // it is leaked so that its destructors are not called at exit. 35 #ifndef DEFINE_STATIC_LOCAL 36 #define DEFINE_STATIC_LOCAL(type, name, arguments) \ 37 static type& name = *new type arguments 38 #endif 39 40 // Use this to declare and define a static local pointer to a ref-counted object so that 41 // it is leaked so that the object's destructors are not called at exit. 42 // This macro should be used with ref-counted objects rather than DEFINE_STATIC_LOCAL macro, 43 // as this macro does not lead to an extra memory allocation. 44 #ifndef DEFINE_STATIC_REF 45 #define DEFINE_STATIC_REF(type, name, arguments) \ 46 static type* name = PassRefPtr<type>(arguments).leakRef(); 47 #endif 48 49 // Use this macro to declare and define a debug-only global variable that may have a 50 // non-trivial constructor and destructor. When building with clang, this will suppress 51 // warnings about global constructors and exit-time destructors. 52 #ifndef NDEBUG 53 #if COMPILER(CLANG) 54 #define DEFINE_DEBUG_ONLY_GLOBAL(type, name, arguments) \ 55 _Pragma("clang diagnostic push") \ 56 _Pragma("clang diagnostic ignored \"-Wglobal-constructors\"") \ 57 _Pragma("clang diagnostic ignored \"-Wexit-time-destructors\"") \ 58 static type name arguments; \ 59 _Pragma("clang diagnostic pop") 60 #else 61 #define DEFINE_DEBUG_ONLY_GLOBAL(type, name, arguments) \ 62 static type name arguments; 63 #endif // COMPILER(CLANG) 64 #else 65 #define DEFINE_DEBUG_ONLY_GLOBAL(type, name, arguments) 66 #endif // NDEBUG 67 68 /* 69 * The reinterpret_cast<Type1*>([pointer to Type2]) expressions - where 70 * sizeof(Type1) > sizeof(Type2) - cause the following warning on ARM with GCC: 71 * increases required alignment of target type. 72 * 73 * An implicit or an extra static_cast<void*> bypasses the warning. 74 * For more info see the following bugzilla entries: 75 * - https://bugs.webkit.org/show_bug.cgi?id=38045 76 * - http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43976 77 */ 78 #if CPU(ARM) && COMPILER(GCC) 79 template<typename Type> 80 bool isPointerTypeAlignmentOkay(Type* ptr) 81 { 82 return !(reinterpret_cast<intptr_t>(ptr) % __alignof__(Type)); 83 } 84 85 template<typename TypePtr> 86 TypePtr reinterpret_cast_ptr(void* ptr) 87 { 88 ASSERT(isPointerTypeAlignmentOkay(reinterpret_cast<TypePtr>(ptr))); 89 return reinterpret_cast<TypePtr>(ptr); 90 } 91 92 template<typename TypePtr> 93 TypePtr reinterpret_cast_ptr(const void* ptr) 94 { 95 ASSERT(isPointerTypeAlignmentOkay(reinterpret_cast<TypePtr>(ptr))); 96 return reinterpret_cast<TypePtr>(ptr); 97 } 98 #else 99 template<typename Type> 100 bool isPointerTypeAlignmentOkay(Type*) 101 { 102 return true; 103 } 104 #define reinterpret_cast_ptr reinterpret_cast 105 #endif 106 107 namespace WTF { 108 109 /* 110 * C++'s idea of a reinterpret_cast lacks sufficient cojones. 111 */ 112 template<typename TO, typename FROM> 113 inline TO bitwise_cast(FROM from) 114 { 115 COMPILE_ASSERT(sizeof(TO) == sizeof(FROM), WTF_bitwise_cast_sizeof_casted_types_is_equal); 116 union { 117 FROM from; 118 TO to; 119 } u; 120 u.from = from; 121 return u.to; 122 } 123 124 template<typename To, typename From> 125 inline To safeCast(From value) 126 { 127 ASSERT(isInBounds<To>(value)); 128 return static_cast<To>(value); 129 } 130 131 // Macro that returns a compile time constant with the length of an array, but gives an error if passed a non-array. 132 template<typename T, size_t Size> char (&ArrayLengthHelperFunction(T (&)[Size]))[Size]; 133 // GCC needs some help to deduce a 0 length array. 134 #if COMPILER(GCC) 135 template<typename T> char (&ArrayLengthHelperFunction(T (&)[0]))[0]; 136 #endif 137 #define WTF_ARRAY_LENGTH(array) sizeof(::WTF::ArrayLengthHelperFunction(array)) 138 139 } // namespace WTF 140 141 // This version of placement new omits a 0 check. 142 enum NotNullTag { NotNull }; 143 inline void* operator new(size_t, NotNullTag, void* location) 144 { 145 ASSERT(location); 146 return location; 147 } 148 149 using WTF::bitwise_cast; 150 using WTF::safeCast; 151 152 #endif // WTF_StdLibExtras_h 153