1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/mfbt/double-conversion/utils.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,298 @@ 1.4 +// Copyright 2010 the V8 project authors. All rights reserved. 1.5 +// Redistribution and use in source and binary forms, with or without 1.6 +// modification, are permitted provided that the following conditions are 1.7 +// met: 1.8 +// 1.9 +// * Redistributions of source code must retain the above copyright 1.10 +// notice, this list of conditions and the following disclaimer. 1.11 +// * Redistributions in binary form must reproduce the above 1.12 +// copyright notice, this list of conditions and the following 1.13 +// disclaimer in the documentation and/or other materials provided 1.14 +// with the distribution. 1.15 +// * Neither the name of Google Inc. nor the names of its 1.16 +// contributors may be used to endorse or promote products derived 1.17 +// from this software without specific prior written permission. 1.18 +// 1.19 +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1.20 +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1.21 +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1.22 +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1.23 +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 1.24 +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 1.25 +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 1.26 +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 1.27 +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 1.28 +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 1.29 +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1.30 + 1.31 +#ifndef DOUBLE_CONVERSION_UTILS_H_ 1.32 +#define DOUBLE_CONVERSION_UTILS_H_ 1.33 + 1.34 +#include <stdlib.h> 1.35 +#include <string.h> 1.36 + 1.37 +#include "mozilla/Assertions.h" 1.38 +#ifndef ASSERT 1.39 +#define ASSERT(condition) MOZ_ASSERT(condition) 1.40 +#endif 1.41 +#ifndef UNIMPLEMENTED 1.42 +#define UNIMPLEMENTED() MOZ_CRASH() 1.43 +#endif 1.44 +#ifndef UNREACHABLE 1.45 +#define UNREACHABLE() MOZ_CRASH() 1.46 +#endif 1.47 + 1.48 +// Double operations detection based on target architecture. 1.49 +// Linux uses a 80bit wide floating point stack on x86. This induces double 1.50 +// rounding, which in turn leads to wrong results. 1.51 +// An easy way to test if the floating-point operations are correct is to 1.52 +// evaluate: 89255.0/1e22. If the floating-point stack is 64 bits wide then 1.53 +// the result is equal to 89255e-22. 1.54 +// The best way to test this, is to create a division-function and to compare 1.55 +// the output of the division with the expected result. (Inlining must be 1.56 +// disabled.) 1.57 +// On Linux,x86 89255e-22 != Div_double(89255.0/1e22) 1.58 +#if defined(_M_X64) || defined(__x86_64__) || \ 1.59 + defined(__ARMEL__) || defined(__avr32__) || \ 1.60 + defined(__hppa__) || defined(__ia64__) || \ 1.61 + defined(__mips__) || \ 1.62 + defined(__powerpc__) || defined(__ppc__) || defined(__ppc64__) || \ 1.63 + defined(__sparc__) || defined(__sparc) || defined(__s390__) || \ 1.64 + defined(__SH4__) || defined(__alpha__) || \ 1.65 + defined(_MIPS_ARCH_MIPS32R2) || \ 1.66 + defined(__AARCH64EL__) 1.67 +#define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1 1.68 +#elif defined(_M_IX86) || defined(__i386__) || defined(__i386) 1.69 +#if defined(_WIN32) 1.70 +// Windows uses a 64bit wide floating point stack. 1.71 +#define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1 1.72 +#else 1.73 +#undef DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1.74 +#endif // _WIN32 1.75 +#else 1.76 +#error Target architecture was not detected as supported by Double-Conversion. 1.77 +#endif 1.78 + 1.79 + 1.80 +#include <stdint.h> 1.81 + 1.82 +// The following macro works on both 32 and 64-bit platforms. 1.83 +// Usage: instead of writing 0x1234567890123456 1.84 +// write UINT64_2PART_C(0x12345678,90123456); 1.85 +#define UINT64_2PART_C(a, b) (((static_cast<uint64_t>(a) << 32) + 0x##b##u)) 1.86 + 1.87 + 1.88 +// The expression ARRAY_SIZE(a) is a compile-time constant of type 1.89 +// size_t which represents the number of elements of the given 1.90 +// array. You should only use ARRAY_SIZE on statically allocated 1.91 +// arrays. 1.92 +#ifndef ARRAY_SIZE 1.93 +#define ARRAY_SIZE(a) \ 1.94 + ((sizeof(a) / sizeof(*(a))) / \ 1.95 + static_cast<size_t>(!(sizeof(a) % sizeof(*(a))))) 1.96 +#endif 1.97 + 1.98 +// A macro to disallow the evil copy constructor and operator= functions 1.99 +// This should be used in the private: declarations for a class 1.100 +#ifndef DISALLOW_COPY_AND_ASSIGN 1.101 +#define DISALLOW_COPY_AND_ASSIGN(TypeName) \ 1.102 + TypeName(const TypeName&); \ 1.103 + void operator=(const TypeName&) 1.104 +#endif 1.105 + 1.106 +// A macro to disallow all the implicit constructors, namely the 1.107 +// default constructor, copy constructor and operator= functions. 1.108 +// 1.109 +// This should be used in the private: declarations for a class 1.110 +// that wants to prevent anyone from instantiating it. This is 1.111 +// especially useful for classes containing only static methods. 1.112 +#ifndef DISALLOW_IMPLICIT_CONSTRUCTORS 1.113 +#define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \ 1.114 + TypeName(); \ 1.115 + DISALLOW_COPY_AND_ASSIGN(TypeName) 1.116 +#endif 1.117 + 1.118 +namespace double_conversion { 1.119 + 1.120 +static const int kCharSize = sizeof(char); 1.121 + 1.122 +// Returns the maximum of the two parameters. 1.123 +template <typename T> 1.124 +static T Max(T a, T b) { 1.125 + return a < b ? b : a; 1.126 +} 1.127 + 1.128 + 1.129 +// Returns the minimum of the two parameters. 1.130 +template <typename T> 1.131 +static T Min(T a, T b) { 1.132 + return a < b ? a : b; 1.133 +} 1.134 + 1.135 + 1.136 +inline int StrLength(const char* string) { 1.137 + size_t length = strlen(string); 1.138 + ASSERT(length == static_cast<size_t>(static_cast<int>(length))); 1.139 + return static_cast<int>(length); 1.140 +} 1.141 + 1.142 +// This is a simplified version of V8's Vector class. 1.143 +template <typename T> 1.144 +class Vector { 1.145 + public: 1.146 + Vector() : start_(NULL), length_(0) {} 1.147 + Vector(T* data, int length) : start_(data), length_(length) { 1.148 + ASSERT(length == 0 || (length > 0 && data != NULL)); 1.149 + } 1.150 + 1.151 + // Returns a vector using the same backing storage as this one, 1.152 + // spanning from and including 'from', to but not including 'to'. 1.153 + Vector<T> SubVector(int from, int to) { 1.154 + ASSERT(to <= length_); 1.155 + ASSERT(from < to); 1.156 + ASSERT(0 <= from); 1.157 + return Vector<T>(start() + from, to - from); 1.158 + } 1.159 + 1.160 + // Returns the length of the vector. 1.161 + int length() const { return length_; } 1.162 + 1.163 + // Returns whether or not the vector is empty. 1.164 + bool is_empty() const { return length_ == 0; } 1.165 + 1.166 + // Returns the pointer to the start of the data in the vector. 1.167 + T* start() const { return start_; } 1.168 + 1.169 + // Access individual vector elements - checks bounds in debug mode. 1.170 + T& operator[](int index) const { 1.171 + ASSERT(0 <= index && index < length_); 1.172 + return start_[index]; 1.173 + } 1.174 + 1.175 + T& first() { return start_[0]; } 1.176 + 1.177 + T& last() { return start_[length_ - 1]; } 1.178 + 1.179 + private: 1.180 + T* start_; 1.181 + int length_; 1.182 +}; 1.183 + 1.184 + 1.185 +// Helper class for building result strings in a character buffer. The 1.186 +// purpose of the class is to use safe operations that checks the 1.187 +// buffer bounds on all operations in debug mode. 1.188 +class StringBuilder { 1.189 + public: 1.190 + StringBuilder(char* buffer, int size) 1.191 + : buffer_(buffer, size), position_(0) { } 1.192 + 1.193 + ~StringBuilder() { if (!is_finalized()) Finalize(); } 1.194 + 1.195 + int size() const { return buffer_.length(); } 1.196 + 1.197 + // Get the current position in the builder. 1.198 + int position() const { 1.199 + ASSERT(!is_finalized()); 1.200 + return position_; 1.201 + } 1.202 + 1.203 + // Reset the position. 1.204 + void Reset() { position_ = 0; } 1.205 + 1.206 + // Add a single character to the builder. It is not allowed to add 1.207 + // 0-characters; use the Finalize() method to terminate the string 1.208 + // instead. 1.209 + void AddCharacter(char c) { 1.210 + ASSERT(c != '\0'); 1.211 + ASSERT(!is_finalized() && position_ < buffer_.length()); 1.212 + buffer_[position_++] = c; 1.213 + } 1.214 + 1.215 + // Add an entire string to the builder. Uses strlen() internally to 1.216 + // compute the length of the input string. 1.217 + void AddString(const char* s) { 1.218 + AddSubstring(s, StrLength(s)); 1.219 + } 1.220 + 1.221 + // Add the first 'n' characters of the given string 's' to the 1.222 + // builder. The input string must have enough characters. 1.223 + void AddSubstring(const char* s, int n) { 1.224 + ASSERT(!is_finalized() && position_ + n < buffer_.length()); 1.225 + ASSERT(static_cast<size_t>(n) <= strlen(s)); 1.226 + memmove(&buffer_[position_], s, n * kCharSize); 1.227 + position_ += n; 1.228 + } 1.229 + 1.230 + 1.231 + // Add character padding to the builder. If count is non-positive, 1.232 + // nothing is added to the builder. 1.233 + void AddPadding(char c, int count) { 1.234 + for (int i = 0; i < count; i++) { 1.235 + AddCharacter(c); 1.236 + } 1.237 + } 1.238 + 1.239 + // Finalize the string by 0-terminating it and returning the buffer. 1.240 + char* Finalize() { 1.241 + ASSERT(!is_finalized() && position_ < buffer_.length()); 1.242 + buffer_[position_] = '\0'; 1.243 + // Make sure nobody managed to add a 0-character to the 1.244 + // buffer while building the string. 1.245 + ASSERT(strlen(buffer_.start()) == static_cast<size_t>(position_)); 1.246 + position_ = -1; 1.247 + ASSERT(is_finalized()); 1.248 + return buffer_.start(); 1.249 + } 1.250 + 1.251 + private: 1.252 + Vector<char> buffer_; 1.253 + int position_; 1.254 + 1.255 + bool is_finalized() const { return position_ < 0; } 1.256 + 1.257 + DISALLOW_IMPLICIT_CONSTRUCTORS(StringBuilder); 1.258 +}; 1.259 + 1.260 +// The type-based aliasing rule allows the compiler to assume that pointers of 1.261 +// different types (for some definition of different) never alias each other. 1.262 +// Thus the following code does not work: 1.263 +// 1.264 +// float f = foo(); 1.265 +// int fbits = *(int*)(&f); 1.266 +// 1.267 +// The compiler 'knows' that the int pointer can't refer to f since the types 1.268 +// don't match, so the compiler may cache f in a register, leaving random data 1.269 +// in fbits. Using C++ style casts makes no difference, however a pointer to 1.270 +// char data is assumed to alias any other pointer. This is the 'memcpy 1.271 +// exception'. 1.272 +// 1.273 +// Bit_cast uses the memcpy exception to move the bits from a variable of one 1.274 +// type of a variable of another type. Of course the end result is likely to 1.275 +// be implementation dependent. Most compilers (gcc-4.2 and MSVC 2005) 1.276 +// will completely optimize BitCast away. 1.277 +// 1.278 +// There is an additional use for BitCast. 1.279 +// Recent gccs will warn when they see casts that may result in breakage due to 1.280 +// the type-based aliasing rule. If you have checked that there is no breakage 1.281 +// you can use BitCast to cast one pointer type to another. This confuses gcc 1.282 +// enough that it can no longer see that you have cast one pointer type to 1.283 +// another thus avoiding the warning. 1.284 +template <class Dest, class Source> 1.285 +inline Dest BitCast(const Source& source) { 1.286 + static_assert(sizeof(Dest) == sizeof(Source), 1.287 + "BitCast's source and destination types must be the same size"); 1.288 + 1.289 + Dest dest; 1.290 + memmove(&dest, &source, sizeof(dest)); 1.291 + return dest; 1.292 +} 1.293 + 1.294 +template <class Dest, class Source> 1.295 +inline Dest BitCast(Source* source) { 1.296 + return BitCast<Dest>(reinterpret_cast<uintptr_t>(source)); 1.297 +} 1.298 + 1.299 +} // namespace double_conversion 1.300 + 1.301 +#endif // DOUBLE_CONVERSION_UTILS_H_