Imported Upstream version 1.0.0
[platform/upstream/js.git] / js / src / jsnum.h
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 #if defined(XP_WIN) || defined(XP_OS2)
45 #include <float.h>
46 #endif
47 #ifdef SOLARIS
48 #include <ieeefp.h>
49 #endif
50 #include "jsvalue.h"
51
52 #include "jsstdint.h"
53 #include "jsstr.h"
54 #include "jsobj.h"
55
56 /*
57  * JS number (IEEE double) interface.
58  *
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.
63  */
64
65 /*
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).
69  */
70 #if defined(__arm) || defined(__arm32__) || defined(__arm26__) || defined(__arm__)
71 #if !defined(__VFP_FP__)
72 #define FPU_IS_ARM_FPA
73 #endif
74 #endif
75
76 typedef union jsdpun {
77     struct {
78 #if defined(IS_LITTLE_ENDIAN) && !defined(FPU_IS_ARM_FPA)
79         uint32 lo, hi;
80 #else
81         uint32 hi, lo;
82 #endif
83     } s;
84     uint64   u64;
85     jsdouble d;
86 } jsdpun;
87
88 static inline int
89 JSDOUBLE_IS_NaN(jsdouble d)
90 {
91 #ifdef WIN32
92     return _isnan(d);
93 #else
94     return isnan(d);
95 #endif
96 }
97
98 static inline int
99 JSDOUBLE_IS_FINITE(jsdouble d)
100 {
101 #ifdef WIN32
102     return _finite(d);
103 #else
104     return finite(d);
105 #endif
106 }
107
108 static inline int
109 JSDOUBLE_IS_INFINITE(jsdouble d)
110 {
111 #ifdef WIN32
112     int c = _fpclass(d);
113     return c == _FPCLASS_NINF || c == _FPCLASS_PINF;
114 #elif defined(SOLARIS)
115     return !finite(d) && !isnan(d);
116 #else
117     return isinf(d);
118 #endif
119 }
120
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
126
127 static inline bool
128 JSDOUBLE_IS_NEG(jsdouble d)
129 {
130 #ifdef WIN32
131     return JSDOUBLE_IS_NEGZERO(d) || d < 0;
132 #elif defined(SOLARIS)
133     return copysign(1, d) < 0;
134 #else
135     return signbit(d);
136 #endif
137 }
138
139 static inline uint32
140 JS_HASH_DOUBLE(jsdouble d)
141 {
142     jsdpun u;
143     u.d = d;
144     return u.s.lo ^ u.s.hi;
145 }
146
147 #if defined(XP_WIN)
148 #define JSDOUBLE_COMPARE(LVAL, OP, RVAL, IFNAN)                               \
149     ((JSDOUBLE_IS_NaN(LVAL) || JSDOUBLE_IS_NaN(RVAL))                         \
150      ? (IFNAN)                                                                \
151      : (LVAL) OP (RVAL))
152 #else
153 #define JSDOUBLE_COMPARE(LVAL, OP, RVAL, IFNAN) ((LVAL) OP (RVAL))
154 #endif
155
156 extern jsdouble js_NaN;
157 extern jsdouble js_PositiveInfinity;
158 extern jsdouble js_NegativeInfinity;
159
160 /* Initialize number constants and runtime state for the first context. */
161 extern JSBool
162 js_InitRuntimeNumberState(JSContext *cx);
163
164 extern void
165 js_FinishRuntimeNumberState(JSContext *cx);
166
167 /* Initialize the Number class, returning its prototype object. */
168 extern js::Class js_NumberClass;
169
170 inline bool
171 JSObject::isNumber() const
172 {
173     return getClass() == &js_NumberClass;
174 }
175
176 extern JSObject *
177 js_InitNumberClass(JSContext *cx, JSObject *obj);
178
179 /*
180  * String constants for global function names, used in jsapi.c and jsnum.c.
181  */
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[];
188
189 extern JSString * JS_FASTCALL
190 js_IntToString(JSContext *cx, jsint i);
191
192 /*
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().
196  */
197 extern JSString * JS_FASTCALL
198 js_NumberToString(JSContext *cx, jsdouble d);
199
200 namespace js {
201
202 /*
203  * Convert an integer or double (contained in the given value) to a string and
204  * append to the given buffer.
205  */
206 extern bool JS_FASTCALL
207 NumberValueToStringBuffer(JSContext *cx, const Value &v, StringBuffer &sb);
208
209 /* Same as js_NumberToString, different signature. */
210 extern JSFlatString *
211 NumberToString(JSContext *cx, jsdouble d);
212
213 /*
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.
217  */
218 struct ToCStringBuf
219 {
220     /*
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.
224      */
225     static const size_t sbufSize = 34;
226     char sbuf[sbufSize];
227     char *dbuf;     /* must be allocated with js_malloc() */
228
229     ToCStringBuf();
230     ~ToCStringBuf();
231 };
232
233 /*
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().
238  */
239 extern char *
240 NumberToCString(JSContext *cx, ToCStringBuf *cbuf, jsdouble d, jsint base = 10);
241
242 /*
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.
245  */
246 const double DOUBLE_INTEGRAL_PRECISION_LIMIT = uint64(1) << 53;
247
248 /*
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.
256  *
257  * If [start, end) does not begin with a number with the specified base,
258  * *dp == 0 and *endp == start upon return.
259  */
260 extern bool
261 GetPrefixInteger(JSContext *cx, const jschar *start, const jschar *end, int base,
262                  const jschar **endp, jsdouble *dp);
263
264 /*
265  * Convert a value to a number, returning the converted value in 'out' if the
266  * conversion succeeds.
267  */
268 JS_ALWAYS_INLINE bool
269 ValueToNumber(JSContext *cx, const js::Value &v, double *out)
270 {
271     if (v.isNumber()) {
272         *out = v.toNumber();
273         return true;
274     }
275     extern bool ValueToNumberSlow(JSContext *, js::Value, double *);
276     return ValueToNumberSlow(cx, v, out);
277 }
278
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)
282 {
283     if (vp->isNumber())
284         return true;
285     double d;
286     extern bool ValueToNumberSlow(JSContext *, js::Value, double *);
287     if (!ValueToNumberSlow(cx, *vp, &d))
288         return false;
289     vp->setNumber(d);
290     return true;
291 }
292
293 /*
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
296  * failure.
297  */
298 JS_ALWAYS_INLINE bool
299 ValueToECMAInt32(JSContext *cx, const js::Value &v, int32_t *out)
300 {
301     if (v.isInt32()) {
302         *out = v.toInt32();
303         return true;
304     }
305     extern bool ValueToECMAInt32Slow(JSContext *, const js::Value &, int32_t *);
306     return ValueToECMAInt32Slow(cx, v, out);
307 }
308
309 JS_ALWAYS_INLINE bool
310 ValueToECMAUint32(JSContext *cx, const js::Value &v, uint32_t *out)
311 {
312     if (v.isInt32()) {
313         *out = (uint32_t)v.toInt32();
314         return true;
315     }
316     extern bool ValueToECMAUint32Slow(JSContext *, const js::Value &, uint32_t *);
317     return ValueToECMAUint32Slow(cx, v, out);
318 }
319
320 /*
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.
324  */
325 JS_ALWAYS_INLINE bool
326 ValueToInt32(JSContext *cx, const js::Value &v, int32_t *out)
327 {
328     if (v.isInt32()) {
329         *out = v.toInt32();
330         return true;
331     }
332     extern bool ValueToInt32Slow(JSContext *, const js::Value &, int32_t *);
333     return ValueToInt32Slow(cx, v, out);
334 }
335
336 /*
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.
340  */
341 JS_ALWAYS_INLINE bool
342 ValueToUint16(JSContext *cx, const js::Value &v, uint16_t *out)
343 {
344     if (v.isInt32()) {
345         *out = (uint16_t)v.toInt32();
346         return true;
347     }
348     extern bool ValueToUint16Slow(JSContext *, const js::Value &, uint16_t *);
349     return ValueToUint16Slow(cx, v, out);
350 }
351
352 }  /* namespace js */
353
354 /*
355  * Specialized ToInt32 and ToUint32 converters for doubles.
356  */
357 /*
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).
366  */
367 static inline int32
368 js_DoubleToECMAInt32(jsdouble d)
369 {
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;
374     int32 mask32;
375
376     /*
377      * Algorithm Outline
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
386      */
387
388     du.d = d;
389     di_h = du.s.hi;
390
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
394         return 0;
395     }
396
397     if (u_tmp < 0x01f00000) {
398         // |d|<2^31
399         return int32_t(d);
400     }
401
402     if (u_tmp > 0x01f00000) {
403         // |d|>=2^32
404         expon = u_tmp >> 20;
405         shift_amount = expon - 21;
406         duh.u64 = du.u64;
407         mask32 = 0x80000000;
408         if (shift_amount < 32) {
409             mask32 >>= shift_amount;
410             duh.s.hi = du.s.hi & mask32;
411             duh.s.lo = 0;
412         } else {
413             mask32 >>= (shift_amount-32);
414             duh.s.hi = du.s.hi;
415             duh.s.lo = du.s.lo & mask32;
416         }
417         du.d -= duh.d;
418     }
419
420     di_h = du.s.hi;
421
422     // eliminate fractional bits
423     u_tmp = (di_h & 0x7ff00000);
424     if (u_tmp >= 0x41e00000) {
425         // |d|>=2^31
426         expon = u_tmp >> 20;
427         shift_amount = expon - (0x3ff - 11);
428         mask32 = 0x80000000;
429         if (shift_amount < 32) {
430             mask32 >>= shift_amount;
431             du.s.hi &= mask32;
432             du.s.lo = 0;
433         } else {
434             mask32 >>= (shift_amount-32);
435             du.s.lo &= mask32;
436         }
437         two32.s.hi = 0x41f00000 ^ (du.s.hi & 0x80000000);
438         two32.s.lo = 0;
439         du.d -= two32.d;
440     }
441
442     return int32(du.d);
443 #elif defined (__arm__) && defined (__GNUC__)
444     int32_t i;
445     uint32_t    tmp0;
446     uint32_t    tmp1;
447     uint32_t    tmp2;
448     asm (
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.
454
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.
459
460     // Extract the exponent.
461 "   mov     %1, %R4, LSR #20\n"
462 "   bic     %1, %1, #(1 << 11)\n"  // Clear the sign.
463
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"
467
468     // Special Cases
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'.
474     //
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.
479     
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"
485 "   bmi     8f\n"
486
487     //  %1 = (decoded) exponent >= 0
488     //  %R4 = upper mantissa and sign
489
490     // ---- Lower Mantissa ----
491 "   subs    %3, %1, #52\n"         // Calculate exp-52
492 "   bmi     1f\n"
493
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"
505 "   b       2f\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.
509 "   rsb     %3, %1, #52\n"
510 "   mov     %Q4, %Q4, LSR %3\n"
511
512     //  %1 = (decoded) exponent
513     //  %R4 = upper mantissa and sign
514     //  %Q4 = partially-converted integer
515
516 "2:\n"
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
520     // upper word.
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.
526 "   bmi     3f\n"
527
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"
534 "   b       4f\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".
540
541     //  %Q4 = partially-converted integer (lower)
542     //  %R4 = upper mantissa and sign
543     //  %2 = partially-converted integer (upper)
544
545 "4:\n"
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
550     // %R4[31]>>31.
551 "   eor     %Q4, %Q4, %R4, ASR #31\n"
552 "   add     %0, %Q4, %R4, LSR #31\n"
553 "   b       9f\n"
554 "8:\n"
555     // +/-INFINITY, +/-0, subnormals, NaNs, and anything else out-of-range that
556     // will result in a conversion of '0'.
557 "   mov     %0, #0\n"
558 "9:\n"
559     : "=r" (i), "=&r" (tmp0), "=&r" (tmp1), "=&r" (tmp2)
560     : "r" (d)
561     : "cc"
562         );
563     return i;
564 #else
565     int32 i;
566     jsdouble two32, two31;
567
568     if (!JSDOUBLE_IS_FINITE(d))
569         return 0;
570
571     i = (int32) d;
572     if ((jsdouble) i == d)
573         return i;
574
575     two32 = 4294967296.0;
576     two31 = 2147483648.0;
577     d = fmod(d, two32);
578     d = (d >= 0) ? floor(d) : ceil(d) + two32;
579     return (int32) (d >= two31 ? d - two32 : d);
580 #endif
581 }
582
583 uint32
584 js_DoubleToECMAUint32(jsdouble d);
585
586 /*
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.
589  */
590 static inline jsdouble
591 js_DoubleToInteger(jsdouble d)
592 {
593     if (d == 0)
594         return d;
595
596     if (!JSDOUBLE_IS_FINITE(d)) {
597         if (JSDOUBLE_IS_NaN(d))
598             return 0;
599         return d;
600     }
601
602     JSBool neg = (d < 0);
603     d = floor(neg ? -d : d);
604
605     return neg ? -d : d;
606 }
607
608 /*
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.
612  *
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.
617  */
618 extern JSBool
619 js_strtod(JSContext *cx, const jschar *s, const jschar *send,
620           const jschar **ep, jsdouble *dp);
621
622 extern JSBool
623 js_num_valueOf(JSContext *cx, uintN argc, js::Value *vp);
624
625 namespace js {
626
627 static JS_ALWAYS_INLINE bool
628 ValueFitsInInt32(const Value &v, int32_t *pi)
629 {
630     if (v.isInt32()) {
631         *pi = v.toInt32();
632         return true;
633     }
634     return v.isDouble() && JSDOUBLE_IS_INT32(v.toDouble(), pi);
635 }
636
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); }
642 };
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; }
647 };
648
649 template<typename T>
650 static JS_ALWAYS_INLINE bool
651 StringToNumberType(JSContext *cx, JSString *str, T *result)
652 {
653     size_t length = str->length();
654     const jschar *chars = str->getChars(NULL);
655     if (!chars)
656         return false;
657
658     if (length == 1) {
659         jschar c = chars[0];
660         if ('0' <= c && c <= '9') {
661             *result = NumberTraits<T>::toSelfType(T(c - '0'));
662             return true;
663         }
664         if (JS_ISSPACE(c)) {
665             *result = NumberTraits<T>::toSelfType(T(0));
666             return true;
667         }
668         *result = NumberTraits<T>::NaN();
669         return true;
670     }
671
672     const jschar *bp = chars;
673     const jschar *end = chars + length;
674     bp = js_SkipWhiteSpace(bp, end);
675
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;
680         double d;
681         if (!GetPrefixInteger(cx, bp + 2, end, 16, &endptr, &d) ||
682             js_SkipWhiteSpace(endptr, end) != end) {
683             *result = NumberTraits<T>::NaN();
684             return true;
685         }
686         *result = NumberTraits<T>::toSelfType(d);
687         return true;
688     }
689
690     /*
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.
696      */
697     const jschar *ep;
698     double d;
699     if (!js_strtod(cx, bp, end, &ep, &d) || js_SkipWhiteSpace(ep, end) != end) {
700         *result = NumberTraits<T>::NaN();
701         return true;
702     }
703     *result = NumberTraits<T>::toSelfType(d);
704     return true;
705 }
706 }
707
708 #endif /* jsnum_h___ */