LCOV - code coverage report
Current view: directory - js/src - jsnum.h (source / functions) Found Hit Coverage
Test: app.info Lines: 116 110 94.8 %
Date: 2012-06-02 Functions: 16 16 100.0 %

       1                 : /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
       2                 :  *
       3                 :  * ***** BEGIN LICENSE BLOCK *****
       4                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       5                 :  *
       6                 :  * The contents of this file are subject to the Mozilla Public License Version
       7                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       8                 :  * the License. You may obtain a copy of the License at
       9                 :  * http://www.mozilla.org/MPL/
      10                 :  *
      11                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      12                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      13                 :  * for the specific language governing rights and limitations under the
      14                 :  * License.
      15                 :  *
      16                 :  * The Original Code is Mozilla Communicator client code, released
      17                 :  * March 31, 1998.
      18                 :  *
      19                 :  * The Initial Developer of the Original Code is
      20                 :  * Netscape Communications Corporation.
      21                 :  * Portions created by the Initial Developer are Copyright (C) 1998
      22                 :  * the Initial Developer. All Rights Reserved.
      23                 :  *
      24                 :  * Contributor(s):
      25                 :  *
      26                 :  * Alternatively, the contents of this file may be used under the terms of
      27                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
      28                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      29                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      30                 :  * of those above. If you wish to allow use of your version of this file only
      31                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      32                 :  * use your version of this file under the terms of the MPL, indicate your
      33                 :  * decision by deleting the provisions above and replace them with the notice
      34                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      35                 :  * the provisions above, a recipient may use your version of this file under
      36                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      37                 :  *
      38                 :  * ***** END LICENSE BLOCK ***** */
      39                 : 
      40                 : #ifndef jsnum_h___
      41                 : #define jsnum_h___
      42                 : 
      43                 : #include <math.h>
      44                 : 
      45                 : #include "jsobj.h"
      46                 : 
      47                 : /*
      48                 :  * JS number (IEEE double) interface.
      49                 :  *
      50                 :  * JS numbers are optimistically stored in the top 31 bits of 32-bit integers,
      51                 :  * but floating point literals, results that overflow 31 bits, and division and
      52                 :  * modulus operands and results require a 64-bit IEEE double.  These are GC'ed
      53                 :  * and pointed to by 32-bit jsvals on the stack and in object properties.
      54                 :  */
      55                 : 
      56                 : /*
      57                 :  * The ARM architecture supports two floating point models: VFP and FPA. When
      58                 :  * targetting FPA, doubles are mixed-endian on little endian ARMs (meaning that
      59                 :  * the high and low words are in big endian order).
      60                 :  */
      61                 : #if defined(__arm) || defined(__arm32__) || defined(__arm26__) || defined(__arm__)
      62                 : #if !defined(__VFP_FP__)
      63                 : #define FPU_IS_ARM_FPA
      64                 : #endif
      65                 : #endif
      66                 : 
      67                 : /* Low-level floating-point predicates. See bug 640494. */
      68                 : #define JSDOUBLE_HI32_SIGNBIT   0x80000000
      69                 : #define JSDOUBLE_HI32_EXPMASK   0x7ff00000
      70                 : #define JSDOUBLE_HI32_MANTMASK  0x000fffff
      71                 : #define JSDOUBLE_HI32_NAN       0x7ff80000
      72                 : #define JSDOUBLE_LO32_NAN       0x00000000
      73                 : 
      74                 : #define JSDOUBLE_HI32_EXPSHIFT  20
      75                 : #define JSDOUBLE_EXPBIAS        1023
      76                 : 
      77                 : typedef union jsdpun {
      78                 :     struct {
      79                 : #if defined(IS_LITTLE_ENDIAN) && !defined(FPU_IS_ARM_FPA)
      80                 :         uint32_t lo, hi;
      81                 : #else
      82                 :         uint32_t hi, lo;
      83                 : #endif
      84                 :     } s;
      85                 :     uint64_t u64;
      86                 :     double d;
      87                 : } jsdpun;
      88                 : 
      89                 : static inline int
      90         1427822 : JSDOUBLE_IS_NaN(double d)
      91                 : {
      92                 :     jsdpun u;
      93         1427822 :     u.d = d;
      94                 :     return (u.u64 & JSDOUBLE_EXPMASK) == JSDOUBLE_EXPMASK &&
      95         1427822 :            (u.u64 & JSDOUBLE_MANTMASK) != 0;
      96                 : }
      97                 : 
      98                 : static inline int
      99         1079526 : JSDOUBLE_IS_FINITE(double d)
     100                 : {
     101                 :     /* -0 is finite. NaNs are not. */
     102                 :     jsdpun u;
     103         1079526 :     u.d = d;
     104         1079526 :     return (u.u64 & JSDOUBLE_EXPMASK) != JSDOUBLE_EXPMASK;
     105                 : }
     106                 : 
     107                 : static inline int
     108              45 : JSDOUBLE_IS_INFINITE(double d)
     109                 : {
     110                 :     jsdpun u;
     111              45 :     u.d = d;
     112              45 :     return (u.u64 & ~JSDOUBLE_SIGNBIT) == JSDOUBLE_EXPMASK;
     113                 : }
     114                 : 
     115                 : static inline bool
     116            3170 : JSDOUBLE_IS_NEG(double d)
     117                 : {
     118                 :     jsdpun u;
     119            3170 :     u.d = d;
     120            3170 :     return (u.s.hi & JSDOUBLE_HI32_SIGNBIT) != 0;
     121                 : }
     122                 : 
     123                 : static inline uint32_t
     124                 : JS_HASH_DOUBLE(double d)
     125                 : {
     126                 :     jsdpun u;
     127                 :     u.d = d;
     128                 :     return u.s.lo ^ u.s.hi;
     129                 : }
     130                 : 
     131                 : extern double js_NaN;
     132                 : extern double js_PositiveInfinity;
     133                 : extern double js_NegativeInfinity;
     134                 : 
     135                 : namespace js {
     136                 : 
     137                 : extern bool
     138                 : InitRuntimeNumberState(JSRuntime *rt);
     139                 : 
     140                 : extern void
     141                 : FinishRuntimeNumberState(JSRuntime *rt);
     142                 : 
     143                 : } /* namespace js */
     144                 : 
     145                 : /* Initialize the Number class, returning its prototype object. */
     146                 : extern JSObject *
     147                 : js_InitNumberClass(JSContext *cx, JSObject *obj);
     148                 : 
     149                 : /*
     150                 :  * String constants for global function names, used in jsapi.c and jsnum.c.
     151                 :  */
     152                 : extern const char js_Infinity_str[];
     153                 : extern const char js_NaN_str[];
     154                 : extern const char js_isNaN_str[];
     155                 : extern const char js_isFinite_str[];
     156                 : extern const char js_parseFloat_str[];
     157                 : extern const char js_parseInt_str[];
     158                 : 
     159                 : class JSString;
     160                 : class JSFixedString;
     161                 : 
     162                 : extern JSString * JS_FASTCALL
     163                 : js_IntToString(JSContext *cx, int i);
     164                 : 
     165                 : /*
     166                 :  * When base == 10, this function implements ToString() as specified by
     167                 :  * ECMA-262-5 section 9.8.1; but note that it handles integers specially for
     168                 :  * performance.  See also js::NumberToCString().
     169                 :  */
     170                 : extern JSString * JS_FASTCALL
     171                 : js_NumberToString(JSContext *cx, double d);
     172                 : 
     173                 : namespace js {
     174                 : 
     175                 : /*
     176                 :  * Convert an integer or double (contained in the given value) to a string and
     177                 :  * append to the given buffer.
     178                 :  */
     179                 : extern bool JS_FASTCALL
     180                 : NumberValueToStringBuffer(JSContext *cx, const Value &v, StringBuffer &sb);
     181                 : 
     182                 : /* Same as js_NumberToString, different signature. */
     183                 : extern JSFixedString *
     184                 : NumberToString(JSContext *cx, double d);
     185                 : 
     186                 : extern JSFixedString *
     187                 : IndexToString(JSContext *cx, uint32_t index);
     188                 : 
     189                 : /*
     190                 :  * Usually a small amount of static storage is enough, but sometimes we need
     191                 :  * to dynamically allocate much more.  This struct encapsulates that.
     192                 :  * Dynamically allocated memory will be freed when the object is destroyed.
     193                 :  */
     194                 : struct ToCStringBuf
     195                 : {
     196                 :     /*
     197                 :      * The longest possible result that would need to fit in sbuf is
     198                 :      * (-0x80000000).toString(2), which has length 33.  Longer cases are
     199                 :      * possible, but they'll go in dbuf.
     200                 :      */
     201                 :     static const size_t sbufSize = 34;
     202                 :     char sbuf[sbufSize];
     203                 :     char *dbuf;
     204                 : 
     205                 :     ToCStringBuf();
     206                 :     ~ToCStringBuf();
     207                 : };
     208                 : 
     209                 : /*
     210                 :  * Convert a number to a C string.  When base==10, this function implements
     211                 :  * ToString() as specified by ECMA-262-5 section 9.8.1.  It handles integral
     212                 :  * values cheaply.  Return NULL if we ran out of memory.  See also
     213                 :  * js_NumberToCString().
     214                 :  */
     215                 : extern char *
     216                 : NumberToCString(JSContext *cx, ToCStringBuf *cbuf, double d, int base = 10);
     217                 : 
     218                 : /*
     219                 :  * The largest positive integer such that all positive integers less than it
     220                 :  * may be precisely represented using the IEEE-754 double-precision format.
     221                 :  */
     222                 : const double DOUBLE_INTEGRAL_PRECISION_LIMIT = uint64_t(1) << 53;
     223                 : 
     224                 : /*
     225                 :  * Compute the positive integer of the given base described immediately at the
     226                 :  * start of the range [start, end) -- no whitespace-skipping, no magical
     227                 :  * leading-"0" octal or leading-"0x" hex behavior, no "+"/"-" parsing, just
     228                 :  * reading the digits of the integer.  Return the index one past the end of the
     229                 :  * digits of the integer in *endp, and return the integer itself in *dp.  If
     230                 :  * base is 10 or a power of two the returned integer is the closest possible
     231                 :  * double; otherwise extremely large integers may be slightly inaccurate.
     232                 :  *
     233                 :  * If [start, end) does not begin with a number with the specified base,
     234                 :  * *dp == 0 and *endp == start upon return.
     235                 :  */
     236                 : extern bool
     237                 : GetPrefixInteger(JSContext *cx, const jschar *start, const jschar *end, int base,
     238                 :                  const jschar **endp, double *dp);
     239                 : 
     240                 : /* ES5 9.3 ToNumber. */
     241                 : JS_ALWAYS_INLINE bool
     242        88051805 : ToNumber(JSContext *cx, const Value &v, double *out)
     243                 : {
     244        88051805 :     if (v.isNumber()) {
     245        87472437 :         *out = v.toNumber();
     246        87472437 :         return true;
     247                 :     }
     248                 :     extern bool ToNumberSlow(JSContext *cx, js::Value v, double *dp);
     249          579368 :     return ToNumberSlow(cx, v, out);
     250                 : }
     251                 : 
     252                 : /* ES5 9.3 ToNumber, overwriting *vp with the appropriate number value. */
     253                 : JS_ALWAYS_INLINE bool
     254        11028398 : ToNumber(JSContext *cx, Value *vp)
     255                 : {
     256        11028398 :     if (vp->isNumber())
     257        11006748 :         return true;
     258                 :     double d;
     259                 :     extern bool ToNumberSlow(JSContext *cx, js::Value v, double *dp);
     260           21650 :     if (!ToNumberSlow(cx, *vp, &d))
     261               0 :         return false;
     262           21650 :     vp->setNumber(d);
     263           21650 :     return true;
     264                 : }
     265                 : 
     266                 : /*
     267                 :  * Convert a value to an int32_t or uint32_t, according to the ECMA rules for
     268                 :  * ToInt32 and ToUint32. Return converted value in *out on success, !ok on
     269                 :  * failure.
     270                 :  */
     271                 : JS_ALWAYS_INLINE bool
     272       100326246 : ToInt32(JSContext *cx, const js::Value &v, int32_t *out)
     273                 : {
     274       100326246 :     if (v.isInt32()) {
     275        98578295 :         *out = v.toInt32();
     276        98578295 :         return true;
     277                 :     }
     278                 :     extern bool ToInt32Slow(JSContext *cx, const js::Value &v, int32_t *ip);
     279         1747951 :     return ToInt32Slow(cx, v, out);
     280                 : }
     281                 : 
     282                 : JS_ALWAYS_INLINE bool
     283         5375182 : ToUint32(JSContext *cx, const js::Value &v, uint32_t *out)
     284                 : {
     285         5375182 :     if (v.isInt32()) {
     286         5356601 :         *out = (uint32_t)v.toInt32();
     287         5356601 :         return true;
     288                 :     }
     289                 :     extern bool ToUint32Slow(JSContext *cx, const js::Value &v, uint32_t *ip);
     290           18581 :     return ToUint32Slow(cx, v, out);
     291                 : }
     292                 : 
     293                 : /*
     294                 :  * Convert a value to a number, then to an int32_t if it fits by rounding to
     295                 :  * nearest. Return converted value in *out on success, !ok on failure. As a
     296                 :  * side effect, *vp will be mutated to match *out.
     297                 :  */
     298                 : JS_ALWAYS_INLINE bool
     299             405 : NonstandardToInt32(JSContext *cx, const js::Value &v, int32_t *out)
     300                 : {
     301             405 :     if (v.isInt32()) {
     302             405 :         *out = v.toInt32();
     303             405 :         return true;
     304                 :     }
     305                 :     extern bool NonstandardToInt32Slow(JSContext *cx, const js::Value &v, int32_t *ip);
     306               0 :     return NonstandardToInt32Slow(cx, v, out);
     307                 : }
     308                 : 
     309                 : /*
     310                 :  * Convert a value to a number, then to a uint16_t according to the ECMA rules
     311                 :  * for ToUint16. Return converted value on success, !ok on failure. v must be a
     312                 :  * copy of a rooted value.
     313                 :  */
     314                 : JS_ALWAYS_INLINE bool
     315        16020533 : ValueToUint16(JSContext *cx, const js::Value &v, uint16_t *out)
     316                 : {
     317        16020533 :     if (v.isInt32()) {
     318        16019957 :         *out = uint16_t(v.toInt32());
     319        16019957 :         return true;
     320                 :     }
     321                 :     extern bool ValueToUint16Slow(JSContext *cx, const js::Value &v, uint16_t *out);
     322             576 :     return ValueToUint16Slow(cx, v, out);
     323                 : }
     324                 : 
     325                 : JSBool
     326                 : num_parseInt(JSContext *cx, unsigned argc, Value *vp);
     327                 : 
     328                 : }  /* namespace js */
     329                 : 
     330                 : /*
     331                 :  * Specialized ToInt32 and ToUint32 converters for doubles.
     332                 :  */
     333                 : /*
     334                 :  * From the ES3 spec, 9.5
     335                 :  *  2.  If Result(1) is NaN, +0, -0, +Inf, or -Inf, return +0.
     336                 :  *  3.  Compute sign(Result(1)) * floor(abs(Result(1))).
     337                 :  *  4.  Compute Result(3) modulo 2^32; that is, a finite integer value k of Number
     338                 :  *      type with positive sign and less than 2^32 in magnitude such the mathematical
     339                 :  *      difference of Result(3) and k is mathematically an integer multiple of 2^32.
     340                 :  *  5.  If Result(4) is greater than or equal to 2^31, return Result(4)- 2^32,
     341                 :  *  otherwise return Result(4).
     342                 :  */
     343                 : static inline int32_t
     344         1773094 : js_DoubleToECMAInt32(double d)
     345                 : {
     346                 : #if defined(__i386__) || defined(__i386) || defined(__x86_64__) || \
     347                 :     defined(_M_IX86) || defined(_M_X64)
     348                 :     jsdpun du, duh, two32;
     349                 :     uint32_t di_h, u_tmp, expon, shift_amount;
     350                 :     int32_t mask32;
     351                 : 
     352                 :     /*
     353                 :      * Algorithm Outline
     354                 :      *  Step 1. If d is NaN, +/-Inf or |d|>=2^84 or |d|<1, then return 0
     355                 :      *          All of this is implemented based on an exponent comparison.
     356                 :      *  Step 2. If |d|<2^31, then return (int)d
     357                 :      *          The cast to integer (conversion in RZ mode) returns the correct result.
     358                 :      *  Step 3. If |d|>=2^32, d:=fmod(d, 2^32) is taken  -- but without a call
     359                 :      *  Step 4. If |d|>=2^31, then the fractional bits are cleared before
     360                 :      *          applying the correction by 2^32:  d - sign(d)*2^32
     361                 :      *  Step 5. Return (int)d
     362                 :      */
     363                 : 
     364         1773094 :     du.d = d;
     365         1773094 :     di_h = du.s.hi;
     366                 : 
     367         1773094 :     u_tmp = (di_h & 0x7ff00000) - 0x3ff00000;
     368         1773094 :     if (u_tmp >= (0x45300000-0x3ff00000)) {
     369                 :         // d is Nan, +/-Inf or +/-0, or |d|>=2^(32+52) or |d|<1, in which case result=0
     370          379311 :         return 0;
     371                 :     }
     372                 : 
     373         1393783 :     if (u_tmp < 0x01f00000) {
     374                 :         // |d|<2^31
     375          617928 :         return int32_t(d);
     376                 :     }
     377                 : 
     378          775855 :     if (u_tmp > 0x01f00000) {
     379                 :         // |d|>=2^32
     380          534766 :         expon = u_tmp >> 20;
     381          534766 :         shift_amount = expon - 21;
     382          534766 :         duh.u64 = du.u64;
     383          534766 :         mask32 = 0x80000000;
     384          534766 :         if (shift_amount < 32) {
     385          534733 :             mask32 >>= shift_amount;
     386          534733 :             duh.s.hi = du.s.hi & mask32;
     387          534733 :             duh.s.lo = 0;
     388                 :         } else {
     389              33 :             mask32 >>= (shift_amount-32);
     390              33 :             duh.s.hi = du.s.hi;
     391              33 :             duh.s.lo = du.s.lo & mask32;
     392                 :         }
     393          534766 :         du.d -= duh.d;
     394                 :     }
     395                 : 
     396          775855 :     di_h = du.s.hi;
     397                 : 
     398                 :     // eliminate fractional bits
     399          775855 :     u_tmp = (di_h & 0x7ff00000);
     400          775855 :     if (u_tmp >= 0x41e00000) {
     401                 :         // |d|>=2^31
     402          364196 :         expon = u_tmp >> 20;
     403          364196 :         shift_amount = expon - (0x3ff - 11);
     404          364196 :         mask32 = 0x80000000;
     405          364196 :         if (shift_amount < 32) {
     406               0 :             mask32 >>= shift_amount;
     407               0 :             du.s.hi &= mask32;
     408               0 :             du.s.lo = 0;
     409                 :         } else {
     410          364196 :             mask32 >>= (shift_amount-32);
     411          364196 :             du.s.lo &= mask32;
     412                 :         }
     413          364196 :         two32.s.hi = 0x41f00000 ^ (du.s.hi & 0x80000000);
     414          364196 :         two32.s.lo = 0;
     415          364196 :         du.d -= two32.d;
     416                 :     }
     417                 : 
     418          775855 :     return int32_t(du.d);
     419                 : #elif defined (__arm__) && defined (__GNUC__)
     420                 :     int32_t i;
     421                 :     uint32_t    tmp0;
     422                 :     uint32_t    tmp1;
     423                 :     uint32_t    tmp2;
     424                 :     asm (
     425                 :     // We use a pure integer solution here. In the 'softfp' ABI, the argument
     426                 :     // will start in r0 and r1, and VFP can't do all of the necessary ECMA
     427                 :     // conversions by itself so some integer code will be required anyway. A
     428                 :     // hybrid solution is faster on A9, but this pure integer solution is
     429                 :     // notably faster for A8.
     430                 : 
     431                 :     // %0 is the result register, and may alias either of the %[QR]1 registers.
     432                 :     // %Q4 holds the lower part of the mantissa.
     433                 :     // %R4 holds the sign, exponent, and the upper part of the mantissa.
     434                 :     // %1, %2 and %3 are used as temporary values.
     435                 : 
     436                 :     // Extract the exponent.
     437                 : "   mov     %1, %R4, LSR #20\n"
     438                 : "   bic     %1, %1, #(1 << 11)\n"  // Clear the sign.
     439                 : 
     440                 :     // Set the implicit top bit of the mantissa. This clobbers a bit of the
     441                 :     // exponent, but we have already extracted that.
     442                 : "   orr     %R4, %R4, #(1 << 20)\n"
     443                 : 
     444                 :     // Special Cases
     445                 :     //   We should return zero in the following special cases:
     446                 :     //    - Exponent is 0x000 - 1023: +/-0 or subnormal.
     447                 :     //    - Exponent is 0x7ff - 1023: +/-INFINITY or NaN
     448                 :     //      - This case is implicitly handled by the standard code path anyway,
     449                 :     //        as shifting the mantissa up by the exponent will result in '0'.
     450                 :     //
     451                 :     // The result is composed of the mantissa, prepended with '1' and
     452                 :     // bit-shifted left by the (decoded) exponent. Note that because the r1[20]
     453                 :     // is the bit with value '1', r1 is effectively already shifted (left) by
     454                 :     // 20 bits, and r0 is already shifted by 52 bits.
     455                 : 
     456                 :     // Adjust the exponent to remove the encoding offset. If the decoded
     457                 :     // exponent is negative, quickly bail out with '0' as such values round to
     458                 :     // zero anyway. This also catches +/-0 and subnormals.
     459                 : "   sub     %1, %1, #0xff\n"
     460                 : "   subs    %1, %1, #0x300\n"
     461                 : "   bmi     8f\n"
     462                 : 
     463                 :     //  %1 = (decoded) exponent >= 0
     464                 :     //  %R4 = upper mantissa and sign
     465                 : 
     466                 :     // ---- Lower Mantissa ----
     467                 : "   subs    %3, %1, #52\n"         // Calculate exp-52
     468                 : "   bmi     1f\n"
     469                 : 
     470                 :     // Shift r0 left by exp-52.
     471                 :     // Ensure that we don't overflow ARM's 8-bit shift operand range.
     472                 :     // We need to handle anything up to an 11-bit value here as we know that
     473                 :     // 52 <= exp <= 1024 (0x400). Any shift beyond 31 bits results in zero
     474                 :     // anyway, so as long as we don't touch the bottom 5 bits, we can use
     475                 :     // a logical OR to push long shifts into the 32 <= (exp&0xff) <= 255 range.
     476                 : "   bic     %2, %3, #0xff\n"
     477                 : "   orr     %3, %3, %2, LSR #3\n"
     478                 :     // We can now perform a straight shift, avoiding the need for any
     479                 :     // conditional instructions or extra branches.
     480                 : "   mov     %Q4, %Q4, LSL %3\n"
     481                 : "   b       2f\n"
     482                 : "1:\n" // Shift r0 right by 52-exp.
     483                 :     // We know that 0 <= exp < 52, and we can shift up to 255 bits so 52-exp
     484                 :     // will always be a valid shift and we can sk%3 the range check for this case.
     485                 : "   rsb     %3, %1, #52\n"
     486                 : "   mov     %Q4, %Q4, LSR %3\n"
     487                 : 
     488                 :     //  %1 = (decoded) exponent
     489                 :     //  %R4 = upper mantissa and sign
     490                 :     //  %Q4 = partially-converted integer
     491                 : 
     492                 : "2:\n"
     493                 :     // ---- Upper Mantissa ----
     494                 :     // This is much the same as the lower mantissa, with a few different
     495                 :     // boundary checks and some masking to hide the exponent & sign bit in the
     496                 :     // upper word.
     497                 :     // Note that the upper mantissa is pre-shifted by 20 in %R4, but we shift
     498                 :     // it left more to remove the sign and exponent so it is effectively
     499                 :     // pre-shifted by 31 bits.
     500                 : "   subs    %3, %1, #31\n"          // Calculate exp-31
     501                 : "   mov     %1, %R4, LSL #11\n"     // Re-use %1 as a temporary register.
     502                 : "   bmi     3f\n"
     503                 : 
     504                 :     // Shift %R4 left by exp-31.
     505                 :     // Avoid overflowing the 8-bit shift range, as before.
     506                 : "   bic     %2, %3, #0xff\n"
     507                 : "   orr     %3, %3, %2, LSR #3\n"
     508                 :     // Perform the shift.
     509                 : "   mov     %2, %1, LSL %3\n"
     510                 : "   b       4f\n"
     511                 : "3:\n" // Shift r1 right by 31-exp.
     512                 :     // We know that 0 <= exp < 31, and we can shift up to 255 bits so 31-exp
     513                 :     // will always be a valid shift and we can skip the range check for this case.
     514                 : "   rsb     %3, %3, #0\n"          // Calculate 31-exp from -(exp-31)
     515                 : "   mov     %2, %1, LSR %3\n"      // Thumb-2 can't do "LSR %3" in "orr".
     516                 : 
     517                 :     //  %Q4 = partially-converted integer (lower)
     518                 :     //  %R4 = upper mantissa and sign
     519                 :     //  %2 = partially-converted integer (upper)
     520                 : 
     521                 : "4:\n"
     522                 :     // Combine the converted parts.
     523                 : "   orr     %Q4, %Q4, %2\n"
     524                 :     // Negate the result if we have to, and move it to %0 in the process. To
     525                 :     // avoid conditionals, we can do this by inverting on %R4[31], then adding
     526                 :     // %R4[31]>>31.
     527                 : "   eor     %Q4, %Q4, %R4, ASR #31\n"
     528                 : "   add     %0, %Q4, %R4, LSR #31\n"
     529                 : "   b       9f\n"
     530                 : "8:\n"
     531                 :     // +/-INFINITY, +/-0, subnormals, NaNs, and anything else out-of-range that
     532                 :     // will result in a conversion of '0'.
     533                 : "   mov     %0, #0\n"
     534                 : "9:\n"
     535                 :     : "=r" (i), "=&r" (tmp0), "=&r" (tmp1), "=&r" (tmp2)
     536                 :     : "r" (d)
     537                 :     : "cc"
     538                 :         );
     539                 :     return i;
     540                 : #else
     541                 :     int32_t i;
     542                 :     double two32, two31;
     543                 : 
     544                 :     if (!JSDOUBLE_IS_FINITE(d))
     545                 :         return 0;
     546                 : 
     547                 :     i = (int32_t) d;
     548                 :     if ((double) i == d)
     549                 :         return i;
     550                 : 
     551                 :     two32 = 4294967296.0;
     552                 :     two31 = 2147483648.0;
     553                 :     d = fmod(d, two32);
     554                 :     d = (d >= 0) ? floor(d) : ceil(d) + two32;
     555                 :     return (int32_t) (d >= two31 ? d - two32 : d);
     556                 : #endif
     557                 : }
     558                 : 
     559                 : inline uint32_t
     560           21616 : js_DoubleToECMAUint32(double d)
     561                 : {
     562           21616 :     return uint32_t(js_DoubleToECMAInt32(d));
     563                 : }
     564                 : 
     565                 : /*
     566                 :  * Convert a double to an integral number, stored in a double.
     567                 :  * If d is NaN, return 0.  If d is an infinity, return it without conversion.
     568                 :  */
     569                 : static inline double
     570           74476 : js_DoubleToInteger(double d)
     571                 : {
     572           74476 :     if (d == 0)
     573            1518 :         return d;
     574                 : 
     575           72958 :     if (!JSDOUBLE_IS_FINITE(d)) {
     576             378 :         if (JSDOUBLE_IS_NaN(d))
     577             189 :             return 0;
     578             189 :         return d;
     579                 :     }
     580                 : 
     581           72580 :     JSBool neg = (d < 0);
     582           72580 :     d = floor(neg ? -d : d);
     583                 : 
     584           72580 :     return neg ? -d : d;
     585                 : }
     586                 : 
     587                 : /*
     588                 :  * Similar to strtod except that it replaces overflows with infinities of the
     589                 :  * correct sign, and underflows with zeros of the correct sign.  Guaranteed to
     590                 :  * return the closest double number to the given input in dp.
     591                 :  *
     592                 :  * Also allows inputs of the form [+|-]Infinity, which produce an infinity of
     593                 :  * the appropriate sign.  The case of the "Infinity" string must match exactly.
     594                 :  * If the string does not contain a number, set *ep to s and return 0.0 in dp.
     595                 :  * Return false if out of memory.
     596                 :  */
     597                 : extern JSBool
     598                 : js_strtod(JSContext *cx, const jschar *s, const jschar *send,
     599                 :           const jschar **ep, double *dp);
     600                 : 
     601                 : extern JSBool
     602                 : js_num_valueOf(JSContext *cx, unsigned argc, js::Value *vp);
     603                 : 
     604                 : namespace js {
     605                 : 
     606                 : static JS_ALWAYS_INLINE bool
     607        59798669 : ValueFitsInInt32(const Value &v, int32_t *pi)
     608                 : {
     609        59798669 :     if (v.isInt32()) {
     610        44334199 :         *pi = v.toInt32();
     611        44334199 :         return true;
     612                 :     }
     613        15464470 :     return v.isDouble() && JSDOUBLE_IS_INT32(v.toDouble(), pi);
     614                 : }
     615                 : 
     616                 : /*
     617                 :  * Returns true if the given value is definitely an index: that is, the value
     618                 :  * is a number that's an unsigned 32-bit integer.
     619                 :  *
     620                 :  * This method prioritizes common-case speed over accuracy in every case.  It
     621                 :  * can produce false negatives (but not false positives): some values which are
     622                 :  * indexes will be reported not to be indexes by this method.  Users must
     623                 :  * consider this possibility when using this method.
     624                 :  */
     625                 : static JS_ALWAYS_INLINE bool
     626        48366660 : IsDefinitelyIndex(const Value &v, uint32_t *indexp)
     627                 : {
     628        48366660 :     if (v.isInt32() && v.toInt32() >= 0) {
     629        43601805 :         *indexp = v.toInt32();
     630        43601805 :         return true;
     631                 :     }
     632                 : 
     633                 :     int32_t i;
     634         4764855 :     if (v.isDouble() && JSDOUBLE_IS_INT32(v.toDouble(), &i) && i >= 0) {
     635            1073 :         *indexp = uint32_t(i);
     636            1073 :         return true;
     637                 :     }
     638                 : 
     639         4763782 :     return false;
     640                 : }
     641                 : 
     642                 : /* ES5 9.4 ToInteger. */
     643                 : static inline bool
     644         1695328 : ToInteger(JSContext *cx, const js::Value &v, double *dp)
     645                 : {
     646         1695328 :     if (v.isInt32()) {
     647         1675484 :         *dp = v.toInt32();
     648         1675484 :         return true;
     649                 :     }
     650           19844 :     if (v.isDouble()) {
     651             476 :         *dp = v.toDouble();
     652                 :     } else {
     653                 :         extern bool ToNumberSlow(JSContext *cx, Value v, double *dp);
     654           19368 :         if (!ToNumberSlow(cx, v, dp))
     655               0 :             return false;
     656                 :     }
     657           19844 :     *dp = js_DoubleToInteger(*dp);
     658           19844 :     return true;
     659                 : }
     660                 : 
     661                 : } /* namespace js */
     662                 : 
     663                 : #endif /* jsnum_h___ */

Generated by: LCOV version 1.7