bug 524346 - using jsval, not jsdouble *, for nan and +-oo. r=brendan

This commit is contained in:
Igor Bukanov 2009-10-27 13:26:57 +03:00
parent e3678e082a
commit ed4f6edf7f
13 changed files with 119 additions and 136 deletions

View File

@ -127,19 +127,19 @@ JS_Now()
JS_PUBLIC_API(jsval) JS_PUBLIC_API(jsval)
JS_GetNaNValue(JSContext *cx) JS_GetNaNValue(JSContext *cx)
{ {
return DOUBLE_TO_JSVAL(cx->runtime->jsNaN); return cx->runtime->NaNValue;
} }
JS_PUBLIC_API(jsval) JS_PUBLIC_API(jsval)
JS_GetNegativeInfinityValue(JSContext *cx) JS_GetNegativeInfinityValue(JSContext *cx)
{ {
return DOUBLE_TO_JSVAL(cx->runtime->jsNegativeInfinity); return cx->runtime->negativeInfinityValue;
} }
JS_PUBLIC_API(jsval) JS_PUBLIC_API(jsval)
JS_GetPositiveInfinityValue(JSContext *cx) JS_GetPositiveInfinityValue(JSContext *cx)
{ {
return DOUBLE_TO_JSVAL(cx->runtime->jsPositiveInfinity); return cx->runtime->positiveInfinityValue;
} }
JS_PUBLIC_API(jsval) JS_PUBLIC_API(jsval)

View File

@ -1708,11 +1708,11 @@ InitArrayElements(JSContext *cx, JSObject *obj, jsuint start, jsuint count, jsva
JS_ASSERT(start == MAXINDEX); JS_ASSERT(start == MAXINDEX);
jsval tmp[2] = {JSVAL_NULL, JSVAL_NULL}; jsval tmp[2] = {JSVAL_NULL, JSVAL_NULL};
jsdouble* dp = js_NewWeaklyRootedDouble(cx, MAXINDEX);
if (!dp)
return JS_FALSE;
tmp[0] = DOUBLE_TO_JSVAL(dp);
JSAutoTempValueRooter tvr(cx, JS_ARRAY_LENGTH(tmp), tmp); JSAutoTempValueRooter tvr(cx, JS_ARRAY_LENGTH(tmp), tmp);
if (!js_NewDoubleInRootedValue(cx, MAXINDEX, &tmp[0]))
return JS_FALSE;
jsdouble *dp = JSVAL_TO_DOUBLE(tmp[0]);
JS_ASSERT(*dp == MAXINDEX);
JSAutoTempIdRooter idr(cx); JSAutoTempIdRooter idr(cx);
do { do {
tmp[1] = *vector++; tmp[1] = *vector++;

View File

@ -66,8 +66,6 @@
using namespace avmplus; using namespace avmplus;
using namespace nanojit; using namespace nanojit;
extern jsdouble js_NaN;
JS_FRIEND_API(void) JS_FRIEND_API(void)
js_SetTraceableNativeFailed(JSContext *cx) js_SetTraceableNativeFailed(JSContext *cx)
{ {

View File

@ -533,9 +533,9 @@ struct JSRuntime {
JSSetSlotRequest *setSlotRequests; JSSetSlotRequest *setSlotRequests;
/* Well-known numbers held for use by this runtime's contexts. */ /* Well-known numbers held for use by this runtime's contexts. */
jsdouble *jsNaN; jsval NaNValue;
jsdouble *jsNegativeInfinity; jsval negativeInfinityValue;
jsdouble *jsPositiveInfinity; jsval positiveInfinityValue;
#ifdef JS_THREADSAFE #ifdef JS_THREADSAFE
JSLock *deflatedStringCacheLock; JSLock *deflatedStringCacheLock;

View File

@ -478,7 +478,7 @@ msFromTime(jsdouble t)
#define TIMECLIP(d) ((JSDOUBLE_IS_FINITE(d) \ #define TIMECLIP(d) ((JSDOUBLE_IS_FINITE(d) \
&& !((d < 0 ? -d : d) > HalfTimeDomain)) \ && !((d < 0 ? -d : d) > HalfTimeDomain)) \
? js_DoubleToInteger(d + (+0.)) : *cx->runtime->jsNaN) ? js_DoubleToInteger(d + (+0.)) : js_NaN)
/** /**
* end of ECMA 'support' functions * end of ECMA 'support' functions
@ -595,7 +595,7 @@ date_msecFromArgs(JSContext *cx, uintN argc, jsval *argv, jsdouble *rval)
return JS_FALSE; return JS_FALSE;
/* return NaN if any arg is not finite */ /* return NaN if any arg is not finite */
if (!JSDOUBLE_IS_FINITE(d)) { if (!JSDOUBLE_IS_FINITE(d)) {
*rval = *cx->runtime->jsNaN; *rval = js_NaN;
return JS_TRUE; return JS_TRUE;
} }
array[loop] = js_DoubleToInteger(d); array[loop] = js_DoubleToInteger(d);
@ -1164,16 +1164,16 @@ date_parse(JSContext *cx, uintN argc, jsval *vp)
jsdouble result; jsdouble result;
if (argc == 0) { if (argc == 0) {
*vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN); *vp = cx->runtime->NaNValue;
return JS_TRUE; return true;
} }
str = js_ValueToString(cx, vp[2]); str = js_ValueToString(cx, vp[2]);
if (!str) if (!str)
return JS_FALSE; return JS_FALSE;
vp[2] = STRING_TO_JSVAL(str); vp[2] = STRING_TO_JSVAL(str);
if (!date_parseString(str, &result)) { if (!date_parseString(str, &result)) {
*vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN); *vp = cx->runtime->NaNValue;
return JS_TRUE; return true;
} }
result = TIMECLIP(result); result = TIMECLIP(result);
@ -1218,11 +1218,10 @@ SetDateToNaN(JSContext *cx, JSObject *obj, jsval *vp = NULL)
{ {
JS_ASSERT(OBJ_GET_CLASS(cx, obj) == &js_DateClass); JS_ASSERT(OBJ_GET_CLASS(cx, obj) == &js_DateClass);
jsval nan = DOUBLE_TO_JSVAL(cx->runtime->jsNaN); obj->fslots[JSSLOT_LOCAL_TIME] = cx->runtime->NaNValue;
obj->fslots[JSSLOT_LOCAL_TIME] = nan; obj->fslots[JSSLOT_UTC_TIME] = cx->runtime->NaNValue;
obj->fslots[JSSLOT_UTC_TIME] = nan;
if (vp) if (vp)
*vp = nan; *vp = cx->runtime->NaNValue;
} }
/* /*
@ -1233,7 +1232,7 @@ SetUTCTime(JSContext *cx, JSObject *obj, jsdouble t, jsval *vp = NULL)
{ {
JS_ASSERT(OBJ_GET_CLASS(cx, obj) == &js_DateClass); JS_ASSERT(OBJ_GET_CLASS(cx, obj) == &js_DateClass);
obj->fslots[JSSLOT_LOCAL_TIME] = DOUBLE_TO_JSVAL(cx->runtime->jsNaN); obj->fslots[JSSLOT_LOCAL_TIME] = cx->runtime->NaNValue;
if (!js_NewDoubleInRootedValue(cx, t, &obj->fslots[JSSLOT_UTC_TIME])) if (!js_NewDoubleInRootedValue(cx, t, &obj->fslots[JSSLOT_UTC_TIME]))
return false; return false;
if (vp) if (vp)
@ -1248,33 +1247,24 @@ SetUTCTime(JSContext *cx, JSObject *obj, jsdouble t, jsval *vp = NULL)
static JSBool static JSBool
GetAndCacheLocalTime(JSContext *cx, JSObject *obj, jsval *vp, jsdouble *dp) GetAndCacheLocalTime(JSContext *cx, JSObject *obj, jsval *vp, jsdouble *dp)
{ {
jsval v;
jsdouble result;
jsdouble *cached;
if (!obj || !JS_InstanceOf(cx, obj, &js_DateClass, vp ? vp + 2 : NULL)) if (!obj || !JS_InstanceOf(cx, obj, &js_DateClass, vp ? vp + 2 : NULL))
return JS_FALSE; return false;
v = obj->fslots[JSSLOT_LOCAL_TIME];
result = *JSVAL_TO_DOUBLE(v);
jsval *slotp = &obj->fslots[JSSLOT_LOCAL_TIME];
jsdouble result = *JSVAL_TO_DOUBLE(*vp);
if (JSDOUBLE_IS_NaN(result)) { if (JSDOUBLE_IS_NaN(result)) {
if (!GetUTCTime(cx, obj, vp, &result)) result = *JSVAL_TO_DOUBLE(obj->fslots[JSSLOT_UTC_TIME]);
return JS_FALSE;
/* if result is NaN, it couldn't be finite. */ /* if result is NaN, it couldn't be finite. */
if (JSDOUBLE_IS_FINITE(result)) if (JSDOUBLE_IS_FINITE(result))
result = LocalTime(result); result = LocalTime(result);
cached = js_NewWeaklyRootedDouble(cx, result); if (!js_NewDoubleInRootedValue(cx, result, slotp))
if (!cached) return false;
return JS_FALSE;
obj->fslots[JSSLOT_LOCAL_TIME] = DOUBLE_TO_JSVAL(cached);
} }
*dp = result; *dp = result;
return JS_TRUE; return true;
} }
/* /*

View File

@ -56,8 +56,6 @@
#include "jslibmath.h" #include "jslibmath.h"
#include "jsobj.h" #include "jsobj.h"
extern jsdouble js_NaN;
#ifndef M_E #ifndef M_E
#define M_E 2.7182818284590452354 #define M_E 2.7182818284590452354
#endif #endif
@ -109,7 +107,7 @@ math_abs(JSContext *cx, uintN argc, jsval *vp)
jsdouble x, z; jsdouble x, z;
if (argc == 0) { if (argc == 0) {
*vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN); *vp = cx->runtime->NaNValue;
return JS_TRUE; return JS_TRUE;
} }
x = js_ValueToNumber(cx, &vp[2]); x = js_ValueToNumber(cx, &vp[2]);
@ -125,7 +123,7 @@ math_acos(JSContext *cx, uintN argc, jsval *vp)
jsdouble x, z; jsdouble x, z;
if (argc == 0) { if (argc == 0) {
*vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN); *vp = cx->runtime->NaNValue;
return JS_TRUE; return JS_TRUE;
} }
x = js_ValueToNumber(cx, &vp[2]); x = js_ValueToNumber(cx, &vp[2]);
@ -133,7 +131,7 @@ math_acos(JSContext *cx, uintN argc, jsval *vp)
return JS_FALSE; return JS_FALSE;
#if defined(SOLARIS) && defined(__GNUC__) #if defined(SOLARIS) && defined(__GNUC__)
if (x < -1 || 1 < x) { if (x < -1 || 1 < x) {
*vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN); *vp = cx->runtime->NaNValue;
return JS_TRUE; return JS_TRUE;
} }
#endif #endif
@ -147,7 +145,7 @@ math_asin(JSContext *cx, uintN argc, jsval *vp)
jsdouble x, z; jsdouble x, z;
if (argc == 0) { if (argc == 0) {
*vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN); *vp = cx->runtime->NaNValue;
return JS_TRUE; return JS_TRUE;
} }
x = js_ValueToNumber(cx, &vp[2]); x = js_ValueToNumber(cx, &vp[2]);
@ -155,7 +153,7 @@ math_asin(JSContext *cx, uintN argc, jsval *vp)
return JS_FALSE; return JS_FALSE;
#if defined(SOLARIS) && defined(__GNUC__) #if defined(SOLARIS) && defined(__GNUC__)
if (x < -1 || 1 < x) { if (x < -1 || 1 < x) {
*vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN); *vp = cx->runtime->NaNValue;
return JS_TRUE; return JS_TRUE;
} }
#endif #endif
@ -169,7 +167,7 @@ math_atan(JSContext *cx, uintN argc, jsval *vp)
jsdouble x, z; jsdouble x, z;
if (argc == 0) { if (argc == 0) {
*vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN); *vp = cx->runtime->NaNValue;
return JS_TRUE; return JS_TRUE;
} }
x = js_ValueToNumber(cx, &vp[2]); x = js_ValueToNumber(cx, &vp[2]);
@ -215,7 +213,7 @@ math_atan2(JSContext *cx, uintN argc, jsval *vp)
jsdouble x, y; jsdouble x, y;
if (argc <= 1) { if (argc <= 1) {
*vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN); *vp = cx->runtime->NaNValue;
return JS_TRUE; return JS_TRUE;
} }
x = js_ValueToNumber(cx, &vp[2]); x = js_ValueToNumber(cx, &vp[2]);
@ -243,7 +241,7 @@ js_math_ceil(JSContext *cx, uintN argc, jsval *vp)
jsdouble x, z; jsdouble x, z;
if (argc == 0) { if (argc == 0) {
*vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN); *vp = cx->runtime->NaNValue;
return JS_TRUE; return JS_TRUE;
} }
x = js_ValueToNumber(cx, &vp[2]); x = js_ValueToNumber(cx, &vp[2]);
@ -259,7 +257,7 @@ math_cos(JSContext *cx, uintN argc, jsval *vp)
jsdouble x, z; jsdouble x, z;
if (argc == 0) { if (argc == 0) {
*vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN); *vp = cx->runtime->NaNValue;
return JS_TRUE; return JS_TRUE;
} }
x = js_ValueToNumber(cx, &vp[2]); x = js_ValueToNumber(cx, &vp[2]);
@ -275,7 +273,7 @@ math_exp(JSContext *cx, uintN argc, jsval *vp)
jsdouble x, z; jsdouble x, z;
if (argc == 0) { if (argc == 0) {
*vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN); *vp = cx->runtime->NaNValue;
return JS_TRUE; return JS_TRUE;
} }
x = js_ValueToNumber(cx, &vp[2]); x = js_ValueToNumber(cx, &vp[2]);
@ -283,11 +281,11 @@ math_exp(JSContext *cx, uintN argc, jsval *vp)
return JS_FALSE; return JS_FALSE;
#ifdef _WIN32 #ifdef _WIN32
if (!JSDOUBLE_IS_NaN(x)) { if (!JSDOUBLE_IS_NaN(x)) {
if (x == *cx->runtime->jsPositiveInfinity) { if (x == js_PositiveInfinity) {
*vp = DOUBLE_TO_JSVAL(cx->runtime->jsPositiveInfinity); *vp = cx->runtime->positiveInfinityValue;
return JS_TRUE; return JS_TRUE;
} }
if (x == *cx->runtime->jsNegativeInfinity) { if (x == js_NegativeInfinity) {
*vp = JSVAL_ZERO; *vp = JSVAL_ZERO;
return JS_TRUE; return JS_TRUE;
} }
@ -303,7 +301,7 @@ js_math_floor(JSContext *cx, uintN argc, jsval *vp)
jsdouble x, z; jsdouble x, z;
if (argc == 0) { if (argc == 0) {
*vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN); *vp = cx->runtime->NaNValue;
return JS_TRUE; return JS_TRUE;
} }
x = js_ValueToNumber(cx, &vp[2]); x = js_ValueToNumber(cx, &vp[2]);
@ -319,7 +317,7 @@ math_log(JSContext *cx, uintN argc, jsval *vp)
jsdouble x, z; jsdouble x, z;
if (argc == 0) { if (argc == 0) {
*vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN); *vp = cx->runtime->NaNValue;
return JS_TRUE; return JS_TRUE;
} }
x = js_ValueToNumber(cx, &vp[2]); x = js_ValueToNumber(cx, &vp[2]);
@ -327,7 +325,7 @@ math_log(JSContext *cx, uintN argc, jsval *vp)
return JS_FALSE; return JS_FALSE;
#if defined(SOLARIS) && defined(__GNUC__) #if defined(SOLARIS) && defined(__GNUC__)
if (x < 0) { if (x < 0) {
*vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN); *vp = cx->runtime->NaNValue;
return JS_TRUE; return JS_TRUE;
} }
#endif #endif
@ -338,12 +336,12 @@ math_log(JSContext *cx, uintN argc, jsval *vp)
JSBool JSBool
js_math_max(JSContext *cx, uintN argc, jsval *vp) js_math_max(JSContext *cx, uintN argc, jsval *vp)
{ {
jsdouble x, z = *cx->runtime->jsNegativeInfinity; jsdouble x, z = js_NegativeInfinity;
jsval *argv; jsval *argv;
uintN i; uintN i;
if (argc == 0) { if (argc == 0) {
*vp = DOUBLE_TO_JSVAL(cx->runtime->jsNegativeInfinity); *vp = cx->runtime->negativeInfinityValue;
return JS_TRUE; return JS_TRUE;
} }
argv = vp + 2; argv = vp + 2;
@ -352,7 +350,7 @@ js_math_max(JSContext *cx, uintN argc, jsval *vp)
if (JSVAL_IS_NULL(argv[i])) if (JSVAL_IS_NULL(argv[i]))
return JS_FALSE; return JS_FALSE;
if (JSDOUBLE_IS_NaN(x)) { if (JSDOUBLE_IS_NaN(x)) {
*vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN); *vp = cx->runtime->NaNValue;
return JS_TRUE; return JS_TRUE;
} }
if (x == 0 && x == z) { if (x == 0 && x == z) {
@ -368,12 +366,12 @@ js_math_max(JSContext *cx, uintN argc, jsval *vp)
JSBool JSBool
js_math_min(JSContext *cx, uintN argc, jsval *vp) js_math_min(JSContext *cx, uintN argc, jsval *vp)
{ {
jsdouble x, z = *cx->runtime->jsPositiveInfinity; jsdouble x, z = js_PositiveInfinity;
jsval *argv; jsval *argv;
uintN i; uintN i;
if (argc == 0) { if (argc == 0) {
*vp = DOUBLE_TO_JSVAL(cx->runtime->jsPositiveInfinity); *vp = cx->runtime->positiveInfinityValue;
return JS_TRUE; return JS_TRUE;
} }
argv = vp + 2; argv = vp + 2;
@ -382,7 +380,7 @@ js_math_min(JSContext *cx, uintN argc, jsval *vp)
if (JSVAL_IS_NULL(argv[i])) if (JSVAL_IS_NULL(argv[i]))
return JS_FALSE; return JS_FALSE;
if (JSDOUBLE_IS_NaN(x)) { if (JSDOUBLE_IS_NaN(x)) {
*vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN); *vp = cx->runtime->NaNValue;
return JS_TRUE; return JS_TRUE;
} }
if (x == 0 && x == z) { if (x == 0 && x == z) {
@ -401,7 +399,7 @@ math_pow(JSContext *cx, uintN argc, jsval *vp)
jsdouble x, y, z; jsdouble x, y, z;
if (argc <= 1) { if (argc <= 1) {
*vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN); *vp = cx->runtime->NaNValue;
return JS_TRUE; return JS_TRUE;
} }
x = js_ValueToNumber(cx, &vp[2]); x = js_ValueToNumber(cx, &vp[2]);
@ -415,7 +413,7 @@ math_pow(JSContext *cx, uintN argc, jsval *vp)
* we need to wrap the libm call to make it ECMA compliant. * we need to wrap the libm call to make it ECMA compliant.
*/ */
if (!JSDOUBLE_IS_FINITE(y) && (x == 1.0 || x == -1.0)) { if (!JSDOUBLE_IS_FINITE(y) && (x == 1.0 || x == -1.0)) {
*vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN); *vp = cx->runtime->NaNValue;
return JS_TRUE; return JS_TRUE;
} }
/* pow(x, +-0) is always 1, even for x = NaN. */ /* pow(x, +-0) is always 1, even for x = NaN. */
@ -492,7 +490,7 @@ js_math_round(JSContext *cx, uintN argc, jsval *vp)
jsdouble x, z; jsdouble x, z;
if (argc == 0) { if (argc == 0) {
*vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN); *vp = cx->runtime->NaNValue;
return JS_TRUE; return JS_TRUE;
} }
x = js_ValueToNumber(cx, &vp[2]); x = js_ValueToNumber(cx, &vp[2]);
@ -508,7 +506,7 @@ math_sin(JSContext *cx, uintN argc, jsval *vp)
jsdouble x, z; jsdouble x, z;
if (argc == 0) { if (argc == 0) {
*vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN); *vp = cx->runtime->NaNValue;
return JS_TRUE; return JS_TRUE;
} }
x = js_ValueToNumber(cx, &vp[2]); x = js_ValueToNumber(cx, &vp[2]);
@ -524,7 +522,7 @@ math_sqrt(JSContext *cx, uintN argc, jsval *vp)
jsdouble x, z; jsdouble x, z;
if (argc == 0) { if (argc == 0) {
*vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN); *vp = cx->runtime->NaNValue;
return JS_TRUE; return JS_TRUE;
} }
x = js_ValueToNumber(cx, &vp[2]); x = js_ValueToNumber(cx, &vp[2]);
@ -540,7 +538,7 @@ math_tan(JSContext *cx, uintN argc, jsval *vp)
jsdouble x, z; jsdouble x, z;
if (argc == 0) { if (argc == 0) {
*vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN); *vp = cx->runtime->NaNValue;
return JS_TRUE; return JS_TRUE;
} }
x = js_ValueToNumber(cx, &vp[2]); x = js_ValueToNumber(cx, &vp[2]);
@ -602,13 +600,11 @@ static jsdouble FASTCALL
math_exp_tn(JSContext *cx, jsdouble d) math_exp_tn(JSContext *cx, jsdouble d)
{ {
if (!JSDOUBLE_IS_NaN(d)) { if (!JSDOUBLE_IS_NaN(d)) {
if (d == *cx->runtime->jsPositiveInfinity) { if (d == js_PositiveInfinity)
return *cx->runtime->jsPositiveInfinity; return js_PositiveInfinity;
} if (d == js_NegativeInfinity)
if (d == *cx->runtime->jsNegativeInfinity) {
return 0.0; return 0.0;
} }
}
return exp(d); return exp(d);
} }

View File

@ -141,7 +141,7 @@ num_parseFloat(JSContext *cx, uintN argc, jsval *vp)
const jschar *bp, *end, *ep; const jschar *bp, *end, *ep;
if (argc == 0) { if (argc == 0) {
*vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN); *vp = cx->runtime->NaNValue;
return JS_TRUE; return JS_TRUE;
} }
str = js_ValueToString(cx, vp[2]); str = js_ValueToString(cx, vp[2]);
@ -151,7 +151,7 @@ num_parseFloat(JSContext *cx, uintN argc, jsval *vp)
if (!js_strtod(cx, bp, end, &ep, &d)) if (!js_strtod(cx, bp, end, &ep, &d))
return JS_FALSE; return JS_FALSE;
if (ep == bp) { if (ep == bp) {
*vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN); *vp = cx->runtime->NaNValue;
return JS_TRUE; return JS_TRUE;
} }
return js_NewNumberInRootedValue(cx, d, vp); return js_NewNumberInRootedValue(cx, d, vp);
@ -183,7 +183,7 @@ num_parseInt(JSContext *cx, uintN argc, jsval *vp)
const jschar *bp, *end, *ep; const jschar *bp, *end, *ep;
if (argc == 0) { if (argc == 0) {
*vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN); *vp = cx->runtime->NaNValue;
return JS_TRUE; return JS_TRUE;
} }
if (argc > 1) { if (argc > 1) {
@ -194,7 +194,7 @@ num_parseInt(JSContext *cx, uintN argc, jsval *vp)
radix = 0; radix = 0;
} }
if (radix != 0 && (radix < 2 || radix > 36)) { if (radix != 0 && (radix < 2 || radix > 36)) {
*vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN); *vp = cx->runtime->NaNValue;
return JS_TRUE; return JS_TRUE;
} }
@ -210,7 +210,7 @@ num_parseInt(JSContext *cx, uintN argc, jsval *vp)
if (!js_strtointeger(cx, bp, end, &ep, radix, &d)) if (!js_strtointeger(cx, bp, end, &ep, radix, &d))
return JS_FALSE; return JS_FALSE;
if (ep == bp) { if (ep == bp) {
*vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN); *vp = cx->runtime->NaNValue;
return JS_TRUE; return JS_TRUE;
} }
return js_NewNumberInRootedValue(cx, d, vp); return js_NewNumberInRootedValue(cx, d, vp);
@ -669,7 +669,8 @@ static JSConstDoubleSpec number_constants[] = {
}; };
jsdouble js_NaN; jsdouble js_NaN;
jsdouble js_PositiveInfinity;
jsdouble js_NegativeInfinity;
#if (defined __GNUC__ && defined __i386__) #if (defined __GNUC__ && defined __i386__)
@ -694,41 +695,37 @@ inline void FIX_FPU() {
JSBool JSBool
js_InitRuntimeNumberState(JSContext *cx) js_InitRuntimeNumberState(JSContext *cx)
{ {
JSRuntime *rt; JS_STATIC_ASSERT(JSVAL_NULL == jsval(0));
jsdpun u;
struct lconv *locale;
rt = cx->runtime; JSRuntime *rt = cx->runtime;
JS_ASSERT(!rt->jsNaN); JS_ASSERT(JSVAL_IS_NULL(rt->NaNValue));
FIX_FPU(); FIX_FPU();
jsdpun u;
u.s.hi = JSDOUBLE_HI32_EXPMASK | JSDOUBLE_HI32_MANTMASK; u.s.hi = JSDOUBLE_HI32_EXPMASK | JSDOUBLE_HI32_MANTMASK;
u.s.lo = 0xffffffff; u.s.lo = 0xffffffff;
number_constants[NC_NaN].dval = js_NaN = u.d; number_constants[NC_NaN].dval = js_NaN = u.d;
rt->jsNaN = js_NewWeaklyRootedDouble(cx, js_NaN); if (!js_NewDoubleInRootedValue(cx, u.d, &rt->NaNValue))
if (!rt->jsNaN) return false;
return JS_FALSE;
u.s.hi = JSDOUBLE_HI32_EXPMASK; u.s.hi = JSDOUBLE_HI32_EXPMASK;
u.s.lo = 0x00000000; u.s.lo = 0x00000000;
number_constants[NC_POSITIVE_INFINITY].dval = u.d; number_constants[NC_POSITIVE_INFINITY].dval = js_PositiveInfinity = u.d;
rt->jsPositiveInfinity = js_NewWeaklyRootedDouble(cx, u.d); if (!js_NewDoubleInRootedValue(cx, u.d, &rt->positiveInfinityValue))
if (!rt->jsPositiveInfinity) return false;
return JS_FALSE;
u.s.hi = JSDOUBLE_HI32_SIGNBIT | JSDOUBLE_HI32_EXPMASK; u.s.hi = JSDOUBLE_HI32_SIGNBIT | JSDOUBLE_HI32_EXPMASK;
u.s.lo = 0x00000000; u.s.lo = 0x00000000;
number_constants[NC_NEGATIVE_INFINITY].dval = u.d; number_constants[NC_NEGATIVE_INFINITY].dval = js_NegativeInfinity = u.d;
rt->jsNegativeInfinity = js_NewWeaklyRootedDouble(cx, u.d); if (!js_NewDoubleInRootedValue(cx, u.d, &rt->negativeInfinityValue))
if (!rt->jsNegativeInfinity) return false;
return JS_FALSE;
u.s.hi = 0; u.s.hi = 0;
u.s.lo = 1; u.s.lo = 1;
number_constants[NC_MIN_VALUE].dval = u.d; number_constants[NC_MIN_VALUE].dval = u.d;
locale = localeconv(); struct lconv *locale = localeconv();
rt->thousandsSeparator = rt->thousandsSeparator =
JS_strdup(cx, locale->thousands_sep ? locale->thousands_sep : "'"); JS_strdup(cx, locale->thousands_sep ? locale->thousands_sep : "'");
rt->decimalSeparator = rt->decimalSeparator =
@ -742,15 +739,18 @@ js_InitRuntimeNumberState(JSContext *cx)
void void
js_TraceRuntimeNumberState(JSTracer *trc) js_TraceRuntimeNumberState(JSTracer *trc)
{ {
JSRuntime *rt; JSRuntime *rt = trc->context->runtime;
rt = trc->context->runtime; if (!JSVAL_IS_NULL(rt->NaNValue))
if (rt->jsNaN) JS_CALL_DOUBLE_TRACER(trc, JSVAL_TO_DOUBLE(rt->NaNValue), "NaN");
JS_CALL_DOUBLE_TRACER(trc, rt->jsNaN, "NaN"); if (!JSVAL_IS_NULL(rt->positiveInfinityValue)) {
if (rt->jsPositiveInfinity) JS_CALL_DOUBLE_TRACER(trc, JSVAL_TO_DOUBLE(rt->positiveInfinityValue),
JS_CALL_DOUBLE_TRACER(trc, rt->jsPositiveInfinity, "+Infinity"); "+Infinity");
if (rt->jsNegativeInfinity) }
JS_CALL_DOUBLE_TRACER(trc, rt->jsNegativeInfinity, "-Infinity"); if (!JSVAL_IS_NULL(rt->negativeInfinityValue)) {
JS_CALL_DOUBLE_TRACER(trc, JSVAL_TO_DOUBLE(rt->negativeInfinityValue),
"-Infinity");
}
} }
void void
@ -758,9 +758,9 @@ js_FinishRuntimeNumberState(JSContext *cx)
{ {
JSRuntime *rt = cx->runtime; JSRuntime *rt = cx->runtime;
rt->jsNaN = NULL; rt->NaNValue = JSVAL_NULL;
rt->jsNegativeInfinity = NULL; rt->negativeInfinityValue = JSVAL_NULL;
rt->jsPositiveInfinity = NULL; rt->positiveInfinityValue = JSVAL_NULL;
cx->free((void *) rt->thousandsSeparator); cx->free((void *) rt->thousandsSeparator);
cx->free((void *) rt->decimalSeparator); cx->free((void *) rt->decimalSeparator);
@ -790,14 +790,13 @@ js_InitNumberClass(JSContext *cx, JSObject *obj)
/* ECMA 15.1.1.1 */ /* ECMA 15.1.1.1 */
rt = cx->runtime; rt = cx->runtime;
if (!JS_DefineProperty(cx, obj, js_NaN_str, DOUBLE_TO_JSVAL(rt->jsNaN), if (!JS_DefineProperty(cx, obj, js_NaN_str, rt->NaNValue,
NULL, NULL, JSPROP_PERMANENT)) { NULL, NULL, JSPROP_PERMANENT)) {
return NULL; return NULL;
} }
/* ECMA 15.1.1.2 */ /* ECMA 15.1.1.2 */
if (!JS_DefineProperty(cx, obj, js_Infinity_str, if (!JS_DefineProperty(cx, obj, js_Infinity_str, rt->positiveInfinityValue,
DOUBLE_TO_JSVAL(rt->jsPositiveInfinity),
NULL, NULL, JSPROP_PERMANENT)) { NULL, NULL, JSPROP_PERMANENT)) {
return NULL; return NULL;
} }
@ -942,7 +941,7 @@ js_ValueToNumber(JSContext *cx, jsval *vp)
jsval v; jsval v;
JSString *str; JSString *str;
const jschar *bp, *end, *ep; const jschar *bp, *end, *ep;
jsdouble d, *dp; jsdouble d;
JSObject *obj; JSObject *obj;
v = *vp; v = *vp;
@ -1020,9 +1019,8 @@ js_ValueToNumber(JSContext *cx, jsval *vp)
break; break;
} }
dp = cx->runtime->jsNaN; *vp = cx->runtime->NaNValue;
*vp = DOUBLE_TO_JSVAL(dp); return js_NaN;
return *dp;
} }
int32 int32
@ -1193,15 +1191,15 @@ js_strtod(JSContext *cx, const jschar *s, const jschar *send,
if ((negative = (*istr == '-')) != 0 || *istr == '+') if ((negative = (*istr == '-')) != 0 || *istr == '+')
istr++; istr++;
if (*istr == 'I' && !strncmp(istr, js_Infinity_str, sizeof js_Infinity_str - 1)) { if (*istr == 'I' && !strncmp(istr, js_Infinity_str, sizeof js_Infinity_str - 1)) {
d = *(negative ? cx->runtime->jsNegativeInfinity : cx->runtime->jsPositiveInfinity); d = negative ? js_NegativeInfinity : js_PositiveInfinity;
estr = istr + 8; estr = istr + 8;
} else { } else {
int err; int err;
d = JS_strtod(cstr, &estr, &err); d = JS_strtod(cstr, &estr, &err);
if (d == HUGE_VAL) if (d == HUGE_VAL)
d = *cx->runtime->jsPositiveInfinity; d = js_PositiveInfinity;
else if (d == -HUGE_VAL) else if (d == -HUGE_VAL)
d = *cx->runtime->jsNegativeInfinity; d = js_NegativeInfinity;
} }
i = estr - cstr; i = estr - cstr;
@ -1336,7 +1334,7 @@ js_strtointeger(JSContext *cx, const jschar *s, const jschar *send,
return JS_FALSE; return JS_FALSE;
} }
if (err == JS_DTOA_ERANGE && value == HUGE_VAL) if (err == JS_DTOA_ERANGE && value == HUGE_VAL)
value = *cx->runtime->jsPositiveInfinity; value = js_PositiveInfinity;
cx->free(cstr); cx->free(cstr);
} else if ((base & (base - 1)) == 0) { } else if ((base & (base - 1)) == 0) {
/* /*

View File

@ -169,6 +169,8 @@ JS_HASH_DOUBLE(jsdouble d)
#endif #endif
extern jsdouble js_NaN; extern jsdouble js_NaN;
extern jsdouble js_PositiveInfinity;
extern jsdouble js_NegativeInfinity;
/* Initialize number constants and runtime state for the first context. */ /* Initialize number constants and runtime state for the first context. */
extern JSBool extern JSBool

View File

@ -1095,15 +1095,15 @@ BEGIN_CASE(JSOP_DIV)
#ifdef XP_WIN #ifdef XP_WIN
/* XXX MSVC miscompiles such that (NaN == 0) */ /* XXX MSVC miscompiles such that (NaN == 0) */
if (JSDOUBLE_IS_NaN(d2)) if (JSDOUBLE_IS_NaN(d2))
rval = DOUBLE_TO_JSVAL(rt->jsNaN); rval = rt->NaNValue;
else else
#endif #endif
if (d == 0 || JSDOUBLE_IS_NaN(d)) if (d == 0 || JSDOUBLE_IS_NaN(d))
rval = DOUBLE_TO_JSVAL(rt->jsNaN); rval = rt->NaNValue;
else if (JSDOUBLE_IS_NEG(d) != JSDOUBLE_IS_NEG(d2)) else if (JSDOUBLE_IS_NEG(d) != JSDOUBLE_IS_NEG(d2))
rval = DOUBLE_TO_JSVAL(rt->jsNegativeInfinity); rval = rt->negativeInfinityValue;
else else
rval = DOUBLE_TO_JSVAL(rt->jsPositiveInfinity); rval = rt->positiveInfinityValue;
STORE_OPND(-1, rval); STORE_OPND(-1, rval);
} else { } else {
d /= d2; d /= d2;
@ -1116,7 +1116,7 @@ BEGIN_CASE(JSOP_MOD)
FETCH_NUMBER(cx, -2, d); FETCH_NUMBER(cx, -2, d);
regs.sp--; regs.sp--;
if (d2 == 0) { if (d2 == 0) {
STORE_OPND(-1, DOUBLE_TO_JSVAL(rt->jsNaN)); STORE_OPND(-1, rt->NaNValue);
} else { } else {
d = js_fmod(d, d2); d = js_fmod(d, d2);
STORE_NUMBER(cx, -1, d); STORE_NUMBER(cx, -1, d);

View File

@ -8449,15 +8449,15 @@ FoldBinaryNumeric(JSContext *cx, JSOp op, JSParseNode *pn1, JSParseNode *pn2,
#if defined(XP_WIN) #if defined(XP_WIN)
/* XXX MSVC miscompiles such that (NaN == 0) */ /* XXX MSVC miscompiles such that (NaN == 0) */
if (JSDOUBLE_IS_NaN(d2)) if (JSDOUBLE_IS_NaN(d2))
d = *cx->runtime->jsNaN; d = js_NaN;
else else
#endif #endif
if (d == 0 || JSDOUBLE_IS_NaN(d)) if (d == 0 || JSDOUBLE_IS_NaN(d))
d = *cx->runtime->jsNaN; d = js_NaN;
else if (JSDOUBLE_IS_NEG(d) != JSDOUBLE_IS_NEG(d2)) else if (JSDOUBLE_IS_NEG(d) != JSDOUBLE_IS_NEG(d2))
d = *cx->runtime->jsNegativeInfinity; d = js_NegativeInfinity;
else else
d = *cx->runtime->jsPositiveInfinity; d = js_PositiveInfinity;
} else { } else {
d /= d2; d /= d2;
} }
@ -8465,7 +8465,7 @@ FoldBinaryNumeric(JSContext *cx, JSOp op, JSParseNode *pn1, JSParseNode *pn2,
case JSOP_MOD: case JSOP_MOD:
if (d2 == 0) { if (d2 == 0) {
d = *cx->runtime->jsNaN; d = js_NaN;
} else { } else {
d = js_fmod(d, d2); d = js_fmod(d, d2);
} }

View File

@ -1004,7 +1004,6 @@ out_of_range:
} }
#ifdef JS_TRACER #ifdef JS_TRACER
extern jsdouble js_NaN;
jsdouble FASTCALL jsdouble FASTCALL
js_String_p_charCodeAt(JSString* str, jsdouble d) js_String_p_charCodeAt(JSString* str, jsdouble d)

View File

@ -8659,7 +8659,7 @@ TraceRecorder::equalityHelper(jsval l, jsval r, LIns* l_ins, LIns* r_ins,
args[0] = l_ins, args[1] = cx_ins; args[0] = l_ins, args[1] = cx_ins;
l_ins = lir->insCall(&js_BooleanOrUndefinedToNumber_ci, args); l_ins = lir->insCall(&js_BooleanOrUndefinedToNumber_ci, args);
l = (l == JSVAL_VOID) l = (l == JSVAL_VOID)
? DOUBLE_TO_JSVAL(cx->runtime->jsNaN) ? cx->runtime->NaNValue
: INT_TO_JSVAL(l == JSVAL_TRUE); : INT_TO_JSVAL(l == JSVAL_TRUE);
return equalityHelper(l, r, l_ins, r_ins, negate, return equalityHelper(l, r, l_ins, r_ins, negate,
tryBranchAfterCond, rval); tryBranchAfterCond, rval);
@ -8673,7 +8673,7 @@ TraceRecorder::equalityHelper(jsval l, jsval r, LIns* l_ins, LIns* r_ins,
args[0] = r_ins, args[1] = cx_ins; args[0] = r_ins, args[1] = cx_ins;
r_ins = lir->insCall(&js_BooleanOrUndefinedToNumber_ci, args); r_ins = lir->insCall(&js_BooleanOrUndefinedToNumber_ci, args);
r = (r == JSVAL_VOID) r = (r == JSVAL_VOID)
? DOUBLE_TO_JSVAL(cx->runtime->jsNaN) ? cx->runtime->NaNValue
: INT_TO_JSVAL(r == JSVAL_TRUE); : INT_TO_JSVAL(r == JSVAL_TRUE);
return equalityHelper(l, r, l_ins, r_ins, negate, return equalityHelper(l, r, l_ins, r_ins, negate,
tryBranchAfterCond, rval); tryBranchAfterCond, rval);

View File

@ -5578,7 +5578,7 @@ xml_childIndex(JSContext *cx, uintN argc, jsval *vp)
NON_LIST_XML_METHOD_PROLOG; NON_LIST_XML_METHOD_PROLOG;
parent = xml->parent; parent = xml->parent;
if (!parent || xml->xml_class == JSXML_CLASS_ATTRIBUTE) { if (!parent || xml->xml_class == JSXML_CLASS_ATTRIBUTE) {
*vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN); *vp = cx->runtime->NaNValue;
return JS_TRUE; return JS_TRUE;
} }
for (i = 0, n = JSXML_LENGTH(parent); i < n; i++) { for (i = 0, n = JSXML_LENGTH(parent); i < n; i++) {