1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
3 * ***** BEGIN LICENSE BLOCK *****
4 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
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/
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
16 * The Original Code is Mozilla Communicator client code, released
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.
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.
38 * ***** END LICENSE BLOCK ***** */
44 #if defined(XP_WIN) || defined(XP_OS2)
57 * JS number (IEEE double) interface.
59 * JS numbers are optimistically stored in the top 31 bits of 32-bit integers,
60 * but floating point literals, results that overflow 31 bits, and division and
61 * modulus operands and results require a 64-bit IEEE double. These are GC'ed
62 * and pointed to by 32-bit jsvals on the stack and in object properties.
66 * The ARM architecture supports two floating point models: VFP and FPA. When
67 * targetting FPA, doubles are mixed-endian on little endian ARMs (meaning that
68 * the high and low words are in big endian order).
70 #if defined(__arm) || defined(__arm32__) || defined(__arm26__) || defined(__arm__)
71 #if !defined(__VFP_FP__)
72 #define FPU_IS_ARM_FPA
76 typedef union jsdpun
{
78 #if defined(IS_LITTLE_ENDIAN) && !defined(FPU_IS_ARM_FPA)
89 JSDOUBLE_IS_NaN(jsdouble d
)
99 JSDOUBLE_IS_FINITE(jsdouble d
)
109 JSDOUBLE_IS_INFINITE(jsdouble d
)
113 return c
== _FPCLASS_NINF
|| c
== _FPCLASS_PINF
;
114 #elif defined(SOLARIS)
115 return !finite(d
) && !isnan(d
);
121 #define JSDOUBLE_HI32_SIGNBIT 0x80000000
122 #define JSDOUBLE_HI32_EXPMASK 0x7ff00000
123 #define JSDOUBLE_HI32_MANTMASK 0x000fffff
124 #define JSDOUBLE_HI32_NAN 0x7ff80000
125 #define JSDOUBLE_LO32_NAN 0x00000000
128 JSDOUBLE_IS_NEG(jsdouble d
)
131 return JSDOUBLE_IS_NEGZERO(d
) || d
< 0;
132 #elif defined(SOLARIS)
133 return copysign(1, d
) < 0;
140 JS_HASH_DOUBLE(jsdouble d
)
144 return u
.s
.lo
^ u
.s
.hi
;
148 #define JSDOUBLE_COMPARE(LVAL, OP, RVAL, IFNAN) \
149 ((JSDOUBLE_IS_NaN(LVAL) || JSDOUBLE_IS_NaN(RVAL)) \
153 #define JSDOUBLE_COMPARE(LVAL, OP, RVAL, IFNAN) ((LVAL) OP (RVAL))
156 extern jsdouble js_NaN
;
157 extern jsdouble js_PositiveInfinity
;
158 extern jsdouble js_NegativeInfinity
;
160 /* Initialize number constants and runtime state for the first context. */
162 js_InitRuntimeNumberState(JSContext
*cx
);
165 js_FinishRuntimeNumberState(JSContext
*cx
);
167 /* Initialize the Number class, returning its prototype object. */
168 extern js::Class js_NumberClass
;
171 JSObject::isNumber() const
173 return getClass() == &js_NumberClass
;
177 js_InitNumberClass(JSContext
*cx
, JSObject
*obj
);
180 * String constants for global function names, used in jsapi.c and jsnum.c.
182 extern const char js_Infinity_str
[];
183 extern const char js_NaN_str
[];
184 extern const char js_isNaN_str
[];
185 extern const char js_isFinite_str
[];
186 extern const char js_parseFloat_str
[];
187 extern const char js_parseInt_str
[];
189 extern JSString
* JS_FASTCALL
190 js_IntToString(JSContext
*cx
, jsint i
);
193 * When base == 10, this function implements ToString() as specified by
194 * ECMA-262-5 section 9.8.1; but note that it handles integers specially for
195 * performance. See also js::NumberToCString().
197 extern JSString
* JS_FASTCALL
198 js_NumberToString(JSContext
*cx
, jsdouble d
);
203 * Convert an integer or double (contained in the given value) to a string and
204 * append to the given buffer.
206 extern bool JS_FASTCALL
207 NumberValueToStringBuffer(JSContext
*cx
, const Value
&v
, StringBuffer
&sb
);
209 /* Same as js_NumberToString, different signature. */
210 extern JSFlatString
*
211 NumberToString(JSContext
*cx
, jsdouble d
);
214 * Usually a small amount of static storage is enough, but sometimes we need
215 * to dynamically allocate much more. This struct encapsulates that.
216 * Dynamically allocated memory will be freed when the object is destroyed.
221 * The longest possible result that would need to fit in sbuf is
222 * (-0x80000000).toString(2), which has length 33. Longer cases are
223 * possible, but they'll go in dbuf.
225 static const size_t sbufSize
= 34;
227 char *dbuf
; /* must be allocated with js_malloc() */
234 * Convert a number to a C string. When base==10, this function implements
235 * ToString() as specified by ECMA-262-5 section 9.8.1. It handles integral
236 * values cheaply. Return NULL if we ran out of memory. See also
237 * js_NumberToCString().
240 NumberToCString(JSContext
*cx
, ToCStringBuf
*cbuf
, jsdouble d
, jsint base
= 10);
243 * The largest positive integer such that all positive integers less than it
244 * may be precisely represented using the IEEE-754 double-precision format.
246 const double DOUBLE_INTEGRAL_PRECISION_LIMIT
= uint64(1) << 53;
249 * Compute the positive integer of the given base described immediately at the
250 * start of the range [start, end) -- no whitespace-skipping, no magical
251 * leading-"0" octal or leading-"0x" hex behavior, no "+"/"-" parsing, just
252 * reading the digits of the integer. Return the index one past the end of the
253 * digits of the integer in *endp, and return the integer itself in *dp. If
254 * base is 10 or a power of two the returned integer is the closest possible
255 * double; otherwise extremely large integers may be slightly inaccurate.
257 * If [start, end) does not begin with a number with the specified base,
258 * *dp == 0 and *endp == start upon return.
261 GetPrefixInteger(JSContext
*cx
, const jschar
*start
, const jschar
*end
, int base
,
262 const jschar
**endp
, jsdouble
*dp
);
265 * Convert a value to a number, returning the converted value in 'out' if the
266 * conversion succeeds.
268 JS_ALWAYS_INLINE
bool
269 ValueToNumber(JSContext
*cx
, const js::Value
&v
, double *out
)
275 extern bool ValueToNumberSlow(JSContext
*, js::Value
, double *);
276 return ValueToNumberSlow(cx
, v
, out
);
279 /* Convert a value to a number, replacing 'vp' with the converted value. */
280 JS_ALWAYS_INLINE
bool
281 ValueToNumber(JSContext
*cx
, js::Value
*vp
)
286 extern bool ValueToNumberSlow(JSContext
*, js::Value
, double *);
287 if (!ValueToNumberSlow(cx
, *vp
, &d
))
294 * Convert a value to an int32 or uint32, according to the ECMA rules for
295 * ToInt32 and ToUint32. Return converted value in *out on success, !ok on
298 JS_ALWAYS_INLINE
bool
299 ValueToECMAInt32(JSContext
*cx
, const js::Value
&v
, int32_t *out
)
305 extern bool ValueToECMAInt32Slow(JSContext
*, const js::Value
&, int32_t *);
306 return ValueToECMAInt32Slow(cx
, v
, out
);
309 JS_ALWAYS_INLINE
bool
310 ValueToECMAUint32(JSContext
*cx
, const js::Value
&v
, uint32_t *out
)
313 *out
= (uint32_t)v
.toInt32();
316 extern bool ValueToECMAUint32Slow(JSContext
*, const js::Value
&, uint32_t *);
317 return ValueToECMAUint32Slow(cx
, v
, out
);
321 * Convert a value to a number, then to an int32 if it fits by rounding to
322 * nearest. Return converted value in *out on success, !ok on failure. As a
323 * side effect, *vp will be mutated to match *out.
325 JS_ALWAYS_INLINE
bool
326 ValueToInt32(JSContext
*cx
, const js::Value
&v
, int32_t *out
)
332 extern bool ValueToInt32Slow(JSContext
*, const js::Value
&, int32_t *);
333 return ValueToInt32Slow(cx
, v
, out
);
337 * Convert a value to a number, then to a uint16 according to the ECMA rules
338 * for ToUint16. Return converted value on success, !ok on failure. v must be a
339 * copy of a rooted value.
341 JS_ALWAYS_INLINE
bool
342 ValueToUint16(JSContext
*cx
, const js::Value
&v
, uint16_t *out
)
345 *out
= (uint16_t)v
.toInt32();
348 extern bool ValueToUint16Slow(JSContext
*, const js::Value
&, uint16_t *);
349 return ValueToUint16Slow(cx
, v
, out
);
355 * Specialized ToInt32 and ToUint32 converters for doubles.
358 * From the ES3 spec, 9.5
359 * 2. If Result(1) is NaN, +0, -0, +Inf, or -Inf, return +0.
360 * 3. Compute sign(Result(1)) * floor(abs(Result(1))).
361 * 4. Compute Result(3) modulo 2^32; that is, a finite integer value k of Number
362 * type with positive sign and less than 2^32 in magnitude such the mathematical
363 * difference of Result(3) and k is mathematically an integer multiple of 2^32.
364 * 5. If Result(4) is greater than or equal to 2^31, return Result(4)- 2^32,
365 * otherwise return Result(4).
368 js_DoubleToECMAInt32(jsdouble d
)
370 #if defined(__i386__) || defined(__i386) || defined(__x86_64__) || \
371 defined(_M_IX86) || defined(_M_X64)
372 jsdpun du
, duh
, two32
;
373 uint32 di_h
, u_tmp
, expon
, shift_amount
;
378 * Step 1. If d is NaN, +/-Inf or |d|>=2^84 or |d|<1, then return 0
379 * All of this is implemented based on an exponent comparison.
380 * Step 2. If |d|<2^31, then return (int)d
381 * The cast to integer (conversion in RZ mode) returns the correct result.
382 * Step 3. If |d|>=2^32, d:=fmod(d, 2^32) is taken -- but without a call
383 * Step 4. If |d|>=2^31, then the fractional bits are cleared before
384 * applying the correction by 2^32: d - sign(d)*2^32
385 * Step 5. Return (int)d
391 u_tmp
= (di_h
& 0x7ff00000) - 0x3ff00000;
392 if (u_tmp
>= (0x45300000-0x3ff00000)) {
393 // d is Nan, +/-Inf or +/-0, or |d|>=2^(32+52) or |d|<1, in which case result=0
397 if (u_tmp
< 0x01f00000) {
402 if (u_tmp
> 0x01f00000) {
405 shift_amount
= expon
- 21;
408 if (shift_amount
< 32) {
409 mask32
>>= shift_amount
;
410 duh
.s
.hi
= du
.s
.hi
& mask32
;
413 mask32
>>= (shift_amount
-32);
415 duh
.s
.lo
= du
.s
.lo
& mask32
;
422 // eliminate fractional bits
423 u_tmp
= (di_h
& 0x7ff00000);
424 if (u_tmp
>= 0x41e00000) {
427 shift_amount
= expon
- (0x3ff - 11);
429 if (shift_amount
< 32) {
430 mask32
>>= shift_amount
;
434 mask32
>>= (shift_amount
-32);
437 two32
.s
.hi
= 0x41f00000 ^ (du
.s
.hi
& 0x80000000);
443 #elif defined (__arm__) && defined (__GNUC__)
449 // We use a pure integer solution here. In the 'softfp' ABI, the argument
450 // will start in r0 and r1, and VFP can't do all of the necessary ECMA
451 // conversions by itself so some integer code will be required anyway. A
452 // hybrid solution is faster on A9, but this pure integer solution is
453 // notably faster for A8.
455 // %0 is the result register, and may alias either of the %[QR]1 registers.
456 // %Q4 holds the lower part of the mantissa.
457 // %R4 holds the sign, exponent, and the upper part of the mantissa.
458 // %1, %2 and %3 are used as temporary values.
460 // Extract the exponent.
461 " mov %1, %R4, LSR #20\n"
462 " bic %1, %1, #(1 << 11)\n" // Clear the sign.
464 // Set the implicit top bit of the mantissa. This clobbers a bit of the
465 // exponent, but we have already extracted that.
466 " orr %R4, %R4, #(1 << 20)\n"
469 // We should return zero in the following special cases:
470 // - Exponent is 0x000 - 1023: +/-0 or subnormal.
471 // - Exponent is 0x7ff - 1023: +/-INFINITY or NaN
472 // - This case is implicitly handled by the standard code path anyway,
473 // as shifting the mantissa up by the exponent will result in '0'.
475 // The result is composed of the mantissa, prepended with '1' and
476 // bit-shifted left by the (decoded) exponent. Note that because the r1[20]
477 // is the bit with value '1', r1 is effectively already shifted (left) by
478 // 20 bits, and r0 is already shifted by 52 bits.
480 // Adjust the exponent to remove the encoding offset. If the decoded
481 // exponent is negative, quickly bail out with '0' as such values round to
482 // zero anyway. This also catches +/-0 and subnormals.
483 " sub %1, %1, #0xff\n"
484 " subs %1, %1, #0x300\n"
487 // %1 = (decoded) exponent >= 0
488 // %R4 = upper mantissa and sign
490 // ---- Lower Mantissa ----
491 " subs %3, %1, #52\n" // Calculate exp-52
494 // Shift r0 left by exp-52.
495 // Ensure that we don't overflow ARM's 8-bit shift operand range.
496 // We need to handle anything up to an 11-bit value here as we know that
497 // 52 <= exp <= 1024 (0x400). Any shift beyond 31 bits results in zero
498 // anyway, so as long as we don't touch the bottom 5 bits, we can use
499 // a logical OR to push long shifts into the 32 <= (exp&0xff) <= 255 range.
500 " bic %2, %3, #0xff\n"
501 " orr %3, %3, %2, LSR #3\n"
502 // We can now perform a straight shift, avoiding the need for any
503 // conditional instructions or extra branches.
504 " mov %Q4, %Q4, LSL %3\n"
506 "1:\n" // Shift r0 right by 52-exp.
507 // We know that 0 <= exp < 52, and we can shift up to 255 bits so 52-exp
508 // will always be a valid shift and we can sk%3 the range check for this case.
510 " mov %Q4, %Q4, LSR %3\n"
512 // %1 = (decoded) exponent
513 // %R4 = upper mantissa and sign
514 // %Q4 = partially-converted integer
517 // ---- Upper Mantissa ----
518 // This is much the same as the lower mantissa, with a few different
519 // boundary checks and some masking to hide the exponent & sign bit in the
521 // Note that the upper mantissa is pre-shifted by 20 in %R4, but we shift
522 // it left more to remove the sign and exponent so it is effectively
523 // pre-shifted by 31 bits.
524 " subs %3, %1, #31\n" // Calculate exp-31
525 " mov %1, %R4, LSL #11\n" // Re-use %1 as a temporary register.
528 // Shift %R4 left by exp-31.
529 // Avoid overflowing the 8-bit shift range, as before.
530 " bic %2, %3, #0xff\n"
531 " orr %3, %3, %2, LSR #3\n"
532 // Perform the shift.
533 " mov %2, %1, LSL %3\n"
535 "3:\n" // Shift r1 right by 31-exp.
536 // We know that 0 <= exp < 31, and we can shift up to 255 bits so 31-exp
537 // will always be a valid shift and we can skip the range check for this case.
538 " rsb %3, %3, #0\n" // Calculate 31-exp from -(exp-31)
539 " mov %2, %1, LSR %3\n" // Thumb-2 can't do "LSR %3" in "orr".
541 // %Q4 = partially-converted integer (lower)
542 // %R4 = upper mantissa and sign
543 // %2 = partially-converted integer (upper)
546 // Combine the converted parts.
547 " orr %Q4, %Q4, %2\n"
548 // Negate the result if we have to, and move it to %0 in the process. To
549 // avoid conditionals, we can do this by inverting on %R4[31], then adding
551 " eor %Q4, %Q4, %R4, ASR #31\n"
552 " add %0, %Q4, %R4, LSR #31\n"
555 // +/-INFINITY, +/-0, subnormals, NaNs, and anything else out-of-range that
556 // will result in a conversion of '0'.
559 : "=r" (i
), "=&r" (tmp0
), "=&r" (tmp1
), "=&r" (tmp2
)
566 jsdouble two32
, two31
;
568 if (!JSDOUBLE_IS_FINITE(d
))
572 if ((jsdouble
) i
== d
)
575 two32
= 4294967296.0;
576 two31
= 2147483648.0;
578 d
= (d
>= 0) ? floor(d
) : ceil(d
) + two32
;
579 return (int32
) (d
>= two31
? d
- two32
: d
);
584 js_DoubleToECMAUint32(jsdouble d
);
587 * Convert a jsdouble to an integral number, stored in a jsdouble.
588 * If d is NaN, return 0. If d is an infinity, return it without conversion.
590 static inline jsdouble
591 js_DoubleToInteger(jsdouble d
)
596 if (!JSDOUBLE_IS_FINITE(d
)) {
597 if (JSDOUBLE_IS_NaN(d
))
602 JSBool neg
= (d
< 0);
603 d
= floor(neg
? -d
: d
);
609 * Similar to strtod except that it replaces overflows with infinities of the
610 * correct sign, and underflows with zeros of the correct sign. Guaranteed to
611 * return the closest double number to the given input in dp.
613 * Also allows inputs of the form [+|-]Infinity, which produce an infinity of
614 * the appropriate sign. The case of the "Infinity" string must match exactly.
615 * If the string does not contain a number, set *ep to s and return 0.0 in dp.
616 * Return false if out of memory.
619 js_strtod(JSContext
*cx
, const jschar
*s
, const jschar
*send
,
620 const jschar
**ep
, jsdouble
*dp
);
623 js_num_valueOf(JSContext
*cx
, uintN argc
, js::Value
*vp
);
627 static JS_ALWAYS_INLINE
bool
628 ValueFitsInInt32(const Value
&v
, int32_t *pi
)
634 return v
.isDouble() && JSDOUBLE_IS_INT32(v
.toDouble(), pi
);
637 template<typename T
> struct NumberTraits
{ };
638 template<> struct NumberTraits
<int32
> {
639 static JS_ALWAYS_INLINE int32
NaN() { return 0; }
640 static JS_ALWAYS_INLINE int32
toSelfType(int32 i
) { return i
; }
641 static JS_ALWAYS_INLINE int32
toSelfType(jsdouble d
) { return js_DoubleToECMAUint32(d
); }
643 template<> struct NumberTraits
<jsdouble
> {
644 static JS_ALWAYS_INLINE jsdouble
NaN() { return js_NaN
; }
645 static JS_ALWAYS_INLINE jsdouble
toSelfType(int32 i
) { return i
; }
646 static JS_ALWAYS_INLINE jsdouble
toSelfType(jsdouble d
) { return d
; }
650 static JS_ALWAYS_INLINE
bool
651 StringToNumberType(JSContext
*cx
, JSString
*str
, T
*result
)
653 size_t length
= str
->length();
654 const jschar
*chars
= str
->getChars(NULL
);
660 if ('0' <= c
&& c
<= '9') {
661 *result
= NumberTraits
<T
>::toSelfType(T(c
- '0'));
665 *result
= NumberTraits
<T
>::toSelfType(T(0));
668 *result
= NumberTraits
<T
>::NaN();
672 const jschar
*bp
= chars
;
673 const jschar
*end
= chars
+ length
;
674 bp
= js_SkipWhiteSpace(bp
, end
);
676 /* ECMA doesn't allow signed hex numbers (bug 273467). */
677 if (end
- bp
>= 2 && bp
[0] == '0' && (bp
[1] == 'x' || bp
[1] == 'X')) {
678 /* Looks like a hex number. */
679 const jschar
*endptr
;
681 if (!GetPrefixInteger(cx
, bp
+ 2, end
, 16, &endptr
, &d
) ||
682 js_SkipWhiteSpace(endptr
, end
) != end
) {
683 *result
= NumberTraits
<T
>::NaN();
686 *result
= NumberTraits
<T
>::toSelfType(d
);
691 * Note that ECMA doesn't treat a string beginning with a '0' as
692 * an octal number here. This works because all such numbers will
693 * be interpreted as decimal by js_strtod. Also, any hex numbers
694 * that have made it here (which can only be negative ones) will
695 * be treated as 0 without consuming the 'x' by js_strtod.
699 if (!js_strtod(cx
, bp
, end
, &ep
, &d
) || js_SkipWhiteSpace(ep
, end
) != end
) {
700 *result
= NumberTraits
<T
>::NaN();
703 *result
= NumberTraits
<T
>::toSelfType(d
);
708 #endif /* jsnum_h___ */