1// Copyright 2010 the V8 project authors. All rights reserved. 2// Redistribution and use in source and binary forms, with or without 3// modification, are permitted provided that the following conditions are 4// met: 5// 6// * Redistributions of source code must retain the above copyright 7// notice, this list of conditions and the following disclaimer. 8// * Redistributions in binary form must reproduce the above 9// copyright notice, this list of conditions and the following 10// disclaimer in the documentation and/or other materials provided 11// with the distribution. 12// * Neither the name of Google Inc. nor the names of its 13// contributors may be used to endorse or promote products derived 14// from this software without specific prior written permission. 15// 16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28#ifndef DOUBLE_CONVERSION_UTILS_H_ 29#define DOUBLE_CONVERSION_UTILS_H_ 30 31#include <wtf/Assertions.h> 32#include <stdlib.h> 33#include <string.h> 34 35#define UNIMPLEMENTED ASSERT_NOT_REACHED 36#define UNREACHABLE ASSERT_NOT_REACHED 37 38// Double operations detection based on target architecture. 39// Linux uses a 80bit wide floating point stack on x86. This induces double 40// rounding, which in turn leads to wrong results. 41// An easy way to test if the floating-point operations are correct is to 42// evaluate: 89255.0/1e22. If the floating-point stack is 64 bits wide then 43// the result is equal to 89255e-22. 44// The best way to test this, is to create a division-function and to compare 45// the output of the division with the expected result. (Inlining must be 46// disabled.) 47// On Linux,x86 89255e-22 != Div_double(89255.0/1e22) 48#if defined(_M_X64) || defined(__x86_64__) || \ 49defined(__ARMEL__) || \ 50defined(_MIPS_ARCH_MIPS32R2) 51#define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1 52#elif CPU(MIPS) || CPU(PPC) || CPU(PPC64) || OS(WINCE) || CPU(SH4) || CPU(S390) || CPU(S390X) || CPU(IA64) || CPU(ALPHA) || CPU(ARM64) || CPU(HPPA) 53#define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1 54#elif defined(_M_IX86) || defined(__i386__) 55#if defined(_WIN32) 56// Windows uses a 64bit wide floating point stack. 57#define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1 58#else 59#undef DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 60#endif // _WIN32 61#elif defined(WINCE) || defined(_WIN32_WCE) 62#define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1 63#else 64#error Target architecture was not detected as supported by Double-Conversion. 65#endif 66 67 68#if defined(_WIN32) && !defined(__MINGW32__) 69 70typedef signed char int8_t; 71typedef unsigned char uint8_t; 72typedef short int16_t; // NOLINT 73typedef unsigned short uint16_t; // NOLINT 74typedef int int32_t; 75typedef unsigned int uint32_t; 76typedef __int64 int64_t; 77typedef unsigned __int64 uint64_t; 78// intptr_t and friends are defined in crtdefs.h through stdio.h. 79 80#else 81 82#include <stdint.h> 83 84#endif 85 86// The following macro works on both 32 and 64-bit platforms. 87// Usage: instead of writing 0x1234567890123456 88// write UINT64_2PART_C(0x12345678,90123456); 89#define UINT64_2PART_C(a, b) (((static_cast<uint64_t>(a) << 32) + 0x##b##u)) 90 91 92// The expression ARRAY_SIZE(a) is a compile-time constant of type 93// size_t which represents the number of elements of the given 94// array. You should only use ARRAY_SIZE on statically allocated 95// arrays. 96#define ARRAY_SIZE(a) \ 97((sizeof(a) / sizeof(*(a))) / \ 98static_cast<size_t>(!(sizeof(a) % sizeof(*(a))))) 99 100// A macro to disallow the evil copy constructor and operator= functions 101// This should be used in the private: declarations for a class 102#define DISALLOW_COPY_AND_ASSIGN(TypeName) \ 103TypeName(const TypeName&); \ 104void operator=(const TypeName&) 105 106// A macro to disallow all the implicit constructors, namely the 107// default constructor, copy constructor and operator= functions. 108// 109// This should be used in the private: declarations for a class 110// that wants to prevent anyone from instantiating it. This is 111// especially useful for classes containing only static methods. 112#define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \ 113TypeName(); \ 114DISALLOW_COPY_AND_ASSIGN(TypeName) 115 116namespace WTF { 117 118namespace double_conversion { 119 120 static const int kCharSize = sizeof(char); 121 122 // Returns the maximum of the two parameters. 123 template <typename T> 124 static T Max(T a, T b) { 125 return a < b ? b : a; 126 } 127 128 129 // Returns the minimum of the two parameters. 130 template <typename T> 131 static T Min(T a, T b) { 132 return a < b ? a : b; 133 } 134 135 136 inline int StrLength(const char* string) { 137 size_t length = strlen(string); 138 ASSERT(length == static_cast<size_t>(static_cast<int>(length))); 139 return static_cast<int>(length); 140 } 141 142 // BufferReference abstract a memory buffer. It provides a pointer 143 // to the beginning of the buffer, and the available length. 144 template <typename T> 145 class BufferReference { 146 public: 147 BufferReference() : start_(NULL), length_(0) {} 148 BufferReference(T* data, int length) : start_(data), length_(length) { 149 ASSERT(length == 0 || (length > 0 && data != NULL)); 150 } 151 152 // Returns a vector using the same backing storage as this one, 153 // spanning from and including 'from', to but not including 'to'. 154 BufferReference<T> SubBufferReference(int from, int to) { 155 ASSERT(to <= length_); 156 ASSERT_WITH_SECURITY_IMPLICATION(from < to); 157 ASSERT(0 <= from); 158 return BufferReference<T>(start() + from, to - from); 159 } 160 161 // Returns the length of the vector. 162 int length() const { return length_; } 163 164 // Returns whether or not the vector is empty. 165 bool is_empty() const { return length_ == 0; } 166 167 // Returns the pointer to the start of the data in the vector. 168 T* start() const { return start_; } 169 170 // Access individual vector elements - checks bounds in debug mode. 171 T& operator[](int index) const { 172 ASSERT(0 <= index && index < length_); 173 return start_[index]; 174 } 175 176 T& first() { return start_[0]; } 177 178 T& last() { return start_[length_ - 1]; } 179 180 private: 181 T* start_; 182 int length_; 183 }; 184 185 186 // Helper class for building result strings in a character buffer. The 187 // purpose of the class is to use safe operations that checks the 188 // buffer bounds on all operations in debug mode. 189 class StringBuilder { 190 public: 191 StringBuilder(char* buffer, int size) 192 : buffer_(buffer, size), position_(0) { } 193 194 ~StringBuilder() { if (!is_finalized()) Finalize(); } 195 196 int size() const { return buffer_.length(); } 197 198 // Get the current position in the builder. 199 int position() const { 200 ASSERT(!is_finalized()); 201 return position_; 202 } 203 204 // Set the current position in the builder. 205 void SetPosition(int position) 206 { 207 ASSERT(!is_finalized()); 208 ASSERT_WITH_SECURITY_IMPLICATION(position < size()); 209 position_ = position; 210 } 211 212 // Reset the position. 213 void Reset() { position_ = 0; } 214 215 // Add a single character to the builder. It is not allowed to add 216 // 0-characters; use the Finalize() method to terminate the string 217 // instead. 218 void AddCharacter(char c) { 219 ASSERT(c != '\0'); 220 ASSERT(!is_finalized() && position_ < buffer_.length()); 221 buffer_[position_++] = c; 222 } 223 224 // Add an entire string to the builder. Uses strlen() internally to 225 // compute the length of the input string. 226 void AddString(const char* s) { 227 AddSubstring(s, StrLength(s)); 228 } 229 230 // Add the first 'n' characters of the given string 's' to the 231 // builder. The input string must have enough characters. 232 void AddSubstring(const char* s, int n) { 233 ASSERT(!is_finalized() && position_ + n < buffer_.length()); 234 ASSERT_WITH_SECURITY_IMPLICATION(static_cast<size_t>(n) <= strlen(s)); 235 memcpy(&buffer_[position_], s, n * kCharSize); 236 position_ += n; 237 } 238 239 240 // Add character padding to the builder. If count is non-positive, 241 // nothing is added to the builder. 242 void AddPadding(char c, int count) { 243 for (int i = 0; i < count; i++) { 244 AddCharacter(c); 245 } 246 } 247 248 // Finalize the string by 0-terminating it and returning the buffer. 249 char* Finalize() { 250 ASSERT(!is_finalized() && position_ < buffer_.length()); 251 buffer_[position_] = '\0'; 252 // Make sure nobody managed to add a 0-character to the 253 // buffer while building the string. 254 ASSERT(strlen(buffer_.start()) == static_cast<size_t>(position_)); 255 position_ = -1; 256 ASSERT(is_finalized()); 257 return buffer_.start(); 258 } 259 260 private: 261 BufferReference<char> buffer_; 262 int position_; 263 264 bool is_finalized() const { return position_ < 0; } 265 266 DISALLOW_IMPLICIT_CONSTRUCTORS(StringBuilder); 267 }; 268 269 // The type-based aliasing rule allows the compiler to assume that pointers of 270 // different types (for some definition of different) never alias each other. 271 // Thus the following code does not work: 272 // 273 // float f = foo(); 274 // int fbits = *(int*)(&f); 275 // 276 // The compiler 'knows' that the int pointer can't refer to f since the types 277 // don't match, so the compiler may cache f in a register, leaving random data 278 // in fbits. Using C++ style casts makes no difference, however a pointer to 279 // char data is assumed to alias any other pointer. This is the 'memcpy 280 // exception'. 281 // 282 // Bit_cast uses the memcpy exception to move the bits from a variable of one 283 // type of a variable of another type. Of course the end result is likely to 284 // be implementation dependent. Most compilers (gcc-4.2 and MSVC 2005) 285 // will completely optimize BitCast away. 286 // 287 // There is an additional use for BitCast. 288 // Recent gccs will warn when they see casts that may result in breakage due to 289 // the type-based aliasing rule. If you have checked that there is no breakage 290 // you can use BitCast to cast one pointer type to another. This confuses gcc 291 // enough that it can no longer see that you have cast one pointer type to 292 // another thus avoiding the warning. 293 template <class Dest, class Source> 294 inline Dest BitCast(const Source& source) { 295 // Compile time assertion: sizeof(Dest) == sizeof(Source) 296 // A compile error here means your Dest and Source have different sizes. 297 typedef char VerifySizesAreEqual[sizeof(Dest) == sizeof(Source) ? 1 : -1]; 298 299 Dest dest; 300 memcpy(&dest, &source, sizeof(dest)); 301 return dest; 302 } 303 304 template <class Dest, class Source> 305 inline Dest BitCast(Source* source) { 306 return BitCast<Dest>(reinterpret_cast<uintptr_t>(source)); 307 } 308 309} // namespace double_conversion 310 311} // namespace WTF 312 313#endif // DOUBLE_CONVERSION_UTILS_H_ 314