Home | History | Annotate | Download | only in dtoa
      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 <string.h>
     33 
     34 #define UNIMPLEMENTED ASSERT_NOT_REACHED
     35 #define UNREACHABLE ASSERT_NOT_REACHED
     36 
     37 // Double operations detection based on target architecture.
     38 // Linux uses a 80bit wide floating point stack on x86. This induces double
     39 // rounding, which in turn leads to wrong results.
     40 // An easy way to test if the floating-point operations are correct is to
     41 // evaluate: 89255.0/1e22. If the floating-point stack is 64 bits wide then
     42 // the result is equal to 89255e-22.
     43 // The best way to test this, is to create a division-function and to compare
     44 // the output of the division with the expected result. (Inlining must be
     45 // disabled.)
     46 // On Linux,x86 89255e-22 != Div_double(89255.0/1e22)
     47 #if defined(_M_X64) || defined(__x86_64__) || \
     48 defined(__ARMEL__) || defined(__aarch64__) || \
     49 defined(__MIPSEL__)
     50 #define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1
     51 #elif defined(_M_IX86) || defined(__i386__)
     52 #if defined(_WIN32)
     53 // Windows uses a 64bit wide floating point stack.
     54 #define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1
     55 #else
     56 #undef DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS
     57 #endif  // _WIN32
     58 #else
     59 #error Target architecture was not detected as supported by Double-Conversion.
     60 #endif
     61 
     62 
     63 #if defined(_WIN32) && !defined(__MINGW32__)
     64 
     65 typedef signed char int8_t;
     66 typedef unsigned char uint8_t;
     67 typedef short int16_t;  // NOLINT
     68 typedef unsigned short uint16_t;  // NOLINT
     69 typedef int int32_t;
     70 typedef unsigned int uint32_t;
     71 typedef __int64 int64_t;
     72 typedef unsigned __int64 uint64_t;
     73 // intptr_t and friends are defined in crtdefs.h through stdio.h.
     74 
     75 #else
     76 
     77 #include <stdint.h>
     78 
     79 #endif
     80 
     81 // The following macro works on both 32 and 64-bit platforms.
     82 // Usage: instead of writing 0x1234567890123456
     83 //      write UINT64_2PART_C(0x12345678,90123456);
     84 #define UINT64_2PART_C(a, b) (((static_cast<uint64_t>(a) << 32) + 0x##b##u))
     85 
     86 
     87 // The expression ARRAY_SIZE(a) is a compile-time constant of type
     88 // size_t which represents the number of elements of the given
     89 // array. You should only use ARRAY_SIZE on statically allocated
     90 // arrays.
     91 #define ARRAY_SIZE(a)                                   \
     92 ((sizeof(a) / sizeof(*(a))) /                         \
     93 static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))
     94 
     95 // A macro to disallow the evil copy constructor and operator= functions
     96 // This should be used in the private: declarations for a class
     97 #define DISALLOW_COPY_AND_ASSIGN(TypeName)      \
     98 TypeName(const TypeName&);                    \
     99 void operator=(const TypeName&)
    100 
    101 // A macro to disallow all the implicit constructors, namely the
    102 // default constructor, copy constructor and operator= functions.
    103 //
    104 // This should be used in the private: declarations for a class
    105 // that wants to prevent anyone from instantiating it. This is
    106 // especially useful for classes containing only static methods.
    107 #define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \
    108 TypeName();                                    \
    109 DISALLOW_COPY_AND_ASSIGN(TypeName)
    110 
    111 namespace WTF {
    112 
    113 namespace double_conversion {
    114 
    115     static const int kCharSize = sizeof(char);
    116 
    117     // Returns the maximum of the two parameters.
    118     template <typename T>
    119     static T Max(T a, T b) {
    120         return a < b ? b : a;
    121     }
    122 
    123 
    124     // Returns the minimum of the two parameters.
    125     template <typename T>
    126     static T Min(T a, T b) {
    127         return a < b ? a : b;
    128     }
    129 
    130 
    131     inline int StrLength(const char* string) {
    132         size_t length = strlen(string);
    133         ASSERT(length == static_cast<size_t>(static_cast<int>(length)));
    134         return static_cast<int>(length);
    135     }
    136 
    137     // This is a simplified version of V8's Vector class.
    138     template <typename T>
    139     class Vector {
    140     public:
    141         Vector() : start_(NULL), length_(0) {}
    142         Vector(T* data, int length) : start_(data), length_(length) {
    143             ASSERT(length == 0 || (length > 0 && data != NULL));
    144         }
    145 
    146         // Returns a vector using the same backing storage as this one,
    147         // spanning from and including 'from', to but not including 'to'.
    148         Vector<T> SubVector(int from, int to) {
    149             ASSERT(to <= length_);
    150             ASSERT(from < to);
    151             ASSERT(0 <= from);
    152             return Vector<T>(start() + from, to - from);
    153         }
    154 
    155         // Returns the length of the vector.
    156         int length() const { return length_; }
    157 
    158         // Returns whether or not the vector is empty.
    159         bool is_empty() const { return length_ == 0; }
    160 
    161         // Returns the pointer to the start of the data in the vector.
    162         T* start() const { return start_; }
    163 
    164         // Access individual vector elements - checks bounds in debug mode.
    165         T& operator[](int index) const {
    166             ASSERT(0 <= index && index < length_);
    167             return start_[index];
    168         }
    169 
    170         T& first() { return start_[0]; }
    171 
    172         T& last() { return start_[length_ - 1]; }
    173 
    174     private:
    175         T* start_;
    176         int length_;
    177     };
    178 
    179 
    180     // Helper class for building result strings in a character buffer. The
    181     // purpose of the class is to use safe operations that checks the
    182     // buffer bounds on all operations in debug mode.
    183     class StringBuilder {
    184     public:
    185         StringBuilder(char* buffer, int size)
    186         : buffer_(buffer, size), position_(0) { }
    187 
    188         ~StringBuilder() { if (!is_finalized()) Finalize(); }
    189 
    190         int size() const { return buffer_.length(); }
    191 
    192         // Get the current position in the builder.
    193         int position() const {
    194             ASSERT(!is_finalized());
    195             return position_;
    196         }
    197 
    198         // Set the current position in the builder.
    199         void SetPosition(int position)
    200         {
    201             ASSERT(!is_finalized());
    202             ASSERT_WITH_SECURITY_IMPLICATION(position < size());
    203             position_ = position;
    204         }
    205 
    206         // Reset the position.
    207         void Reset() { position_ = 0; }
    208 
    209         // Add a single character to the builder. It is not allowed to add
    210         // 0-characters; use the Finalize() method to terminate the string
    211         // instead.
    212         void AddCharacter(char c) {
    213             ASSERT(c != '\0');
    214             ASSERT(!is_finalized() && position_ < buffer_.length());
    215             buffer_[position_++] = c;
    216         }
    217 
    218         // Add an entire string to the builder. Uses strlen() internally to
    219         // compute the length of the input string.
    220         void AddString(const char* s) {
    221             AddSubstring(s, StrLength(s));
    222         }
    223 
    224         // Add the first 'n' characters of the given string 's' to the
    225         // builder. The input string must have enough characters.
    226         void AddSubstring(const char* s, int n) {
    227             ASSERT(!is_finalized() && position_ + n < buffer_.length());
    228             ASSERT_WITH_SECURITY_IMPLICATION(static_cast<size_t>(n) <= strlen(s));
    229             memcpy(&buffer_[position_], s, n * kCharSize);
    230             position_ += n;
    231         }
    232 
    233 
    234         // Add character padding to the builder. If count is non-positive,
    235         // nothing is added to the builder.
    236         void AddPadding(char c, int count) {
    237             for (int i = 0; i < count; i++) {
    238                 AddCharacter(c);
    239             }
    240         }
    241 
    242         // Finalize the string by 0-terminating it and returning the buffer.
    243         char* Finalize() {
    244             ASSERT(!is_finalized() && position_ < buffer_.length());
    245             buffer_[position_] = '\0';
    246             // Make sure nobody managed to add a 0-character to the
    247             // buffer while building the string.
    248             ASSERT(strlen(buffer_.start()) == static_cast<size_t>(position_));
    249             position_ = -1;
    250             ASSERT(is_finalized());
    251             return buffer_.start();
    252         }
    253 
    254     private:
    255         Vector<char> buffer_;
    256         int position_;
    257 
    258         bool is_finalized() const { return position_ < 0; }
    259 
    260         DISALLOW_IMPLICIT_CONSTRUCTORS(StringBuilder);
    261     };
    262 
    263     // The type-based aliasing rule allows the compiler to assume that pointers of
    264     // different types (for some definition of different) never alias each other.
    265     // Thus the following code does not work:
    266     //
    267     // float f = foo();
    268     // int fbits = *(int*)(&f);
    269     //
    270     // The compiler 'knows' that the int pointer can't refer to f since the types
    271     // don't match, so the compiler may cache f in a register, leaving random data
    272     // in fbits.  Using C++ style casts makes no difference, however a pointer to
    273     // char data is assumed to alias any other pointer.  This is the 'memcpy
    274     // exception'.
    275     //
    276     // Bit_cast uses the memcpy exception to move the bits from a variable of one
    277     // type of a variable of another type.  Of course the end result is likely to
    278     // be implementation dependent.  Most compilers (gcc-4.2 and MSVC 2005)
    279     // will completely optimize BitCast away.
    280     //
    281     // There is an additional use for BitCast.
    282     // Recent gccs will warn when they see casts that may result in breakage due to
    283     // the type-based aliasing rule.  If you have checked that there is no breakage
    284     // you can use BitCast to cast one pointer type to another.  This confuses gcc
    285     // enough that it can no longer see that you have cast one pointer type to
    286     // another thus avoiding the warning.
    287     template <class Dest, class Source>
    288     inline Dest BitCast(const Source& source) {
    289         // Compile time assertion: sizeof(Dest) == sizeof(Source)
    290         // A compile error here means your Dest and Source have different sizes.
    291         COMPILE_ASSERT(sizeof(Dest) == sizeof(Source), VerifySizesAreEqual);
    292 
    293         Dest dest;
    294         memcpy(&dest, &source, sizeof(dest));
    295         return dest;
    296     }
    297 
    298     template <class Dest, class Source>
    299     inline Dest BitCast(Source* source) {
    300         return BitCast<Dest>(reinterpret_cast<uintptr_t>(source));
    301     }
    302 
    303 }  // namespace double_conversion
    304 
    305 } // namespace WTF
    306 
    307 #endif  // DOUBLE_CONVERSION_UTILS_H_
    308