Home | History | Annotate | Download | only in src
      1 // Copyright 2006-2008 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 V8_CONVERSIONS_INL_H_
     29 #define V8_CONVERSIONS_INL_H_
     30 
     31 #include <math.h>
     32 #include <float.h>         // required for DBL_MAX and on Win32 for finite()
     33 #include <stdarg.h>
     34 
     35 // ----------------------------------------------------------------------------
     36 // Extra POSIX/ANSI functions for Win32/MSVC.
     37 
     38 #include "conversions.h"
     39 #include "platform.h"
     40 
     41 namespace v8 {
     42 namespace internal {
     43 
     44 // The fast double-to-int conversion routine does not guarantee
     45 // rounding towards zero.
     46 static inline int FastD2I(double x) {
     47 #ifdef __USE_ISOC99
     48   // The ISO C99 standard defines the lrint() function which rounds a
     49   // double to an integer according to the current rounding direction.
     50   return lrint(x);
     51 #else
     52   // This is incredibly slow on Intel x86. The reason is that rounding
     53   // towards zero is implied by the C standard. This means that the
     54   // status register of the FPU has to be changed with the 'fldcw'
     55   // instruction. This completely stalls the pipeline and takes many
     56   // hundreds of clock cycles.
     57   return static_cast<int>(x);
     58 #endif
     59 }
     60 
     61 
     62 static inline double DoubleToInteger(double x) {
     63   if (isnan(x)) return 0;
     64   if (!isfinite(x) || x == 0) return x;
     65   return (x >= 0) ? floor(x) : ceil(x);
     66 }
     67 
     68 
     69 int32_t NumberToInt32(Object* number) {
     70   if (number->IsSmi()) return Smi::cast(number)->value();
     71   return DoubleToInt32(number->Number());
     72 }
     73 
     74 
     75 uint32_t NumberToUint32(Object* number) {
     76   if (number->IsSmi()) return Smi::cast(number)->value();
     77   return DoubleToUint32(number->Number());
     78 }
     79 
     80 
     81 int32_t DoubleToInt32(double x) {
     82   int32_t i = FastD2I(x);
     83   if (FastI2D(i) == x) return i;
     84   static const double two32 = 4294967296.0;
     85   static const double two31 = 2147483648.0;
     86   if (!isfinite(x) || x == 0) return 0;
     87   if (x < 0 || x >= two32) x = modulo(x, two32);
     88   x = (x >= 0) ? floor(x) : ceil(x) + two32;
     89   return (int32_t) ((x >= two31) ? x - two32 : x);
     90 }
     91 
     92 
     93 } }  // namespace v8::internal
     94 
     95 #endif  // V8_CONVERSIONS_INL_H_
     96