diff --git a/js/ref/jsapi.c b/js/ref/jsapi.c index 5cdd9cb1bb5..24724a4796e 100644 --- a/js/ref/jsapi.c +++ b/js/ref/jsapi.c @@ -1201,19 +1201,11 @@ JS_DefineConstDoubles(JSContext *cx, JSObject *obj, JSConstDoubleSpec *cds) * so we don't need to GC-alloc constant doubles. */ jsdouble d = cds->dval; + jsint i; - /* We can't do a (jsint) cast to check against JSDOUBLE_IS_INT until we - * know that d is not NaN, or we risk a FPE on some platforms. - */ - if (JSDOUBLE_IS_NaN(d) || !JSDOUBLE_IS_FINITE(d)) { - value = DOUBLE_TO_JSVAL(&cds->dval); - } else { - jsint i = (jsint)d; - - value = (JSDOUBLE_IS_INT(d, i) && INT_FITS_IN_JSVAL(i)) - ? INT_TO_JSVAL(i) - : DOUBLE_TO_JSVAL(&cds->dval); - } + value = (JSDOUBLE_IS_INT(d, i) && INT_FITS_IN_JSVAL(i)) + ? INT_TO_JSVAL(i) + : DOUBLE_TO_JSVAL(&cds->dval); #else ok = js_NewNumberValue(cx, cds->dval, &value); if (!ok) diff --git a/js/ref/jsemit.c b/js/ref/jsemit.c index 8c5cbc0a2e3..caed6742282 100644 --- a/js/ref/jsemit.c +++ b/js/ref/jsemit.c @@ -397,7 +397,6 @@ EmitNumberOp(JSContext *cx, jsdouble dval, JSCodeGenerator *cg) JSAtom *atom; JSAtomListElement *ale; - ival = (jsint)dval; if (JSDOUBLE_IS_INT(dval, ival) && INT_FITS_IN_JSVAL(ival)) { if (ival == 0) return js_Emit1(cx, cg, JSOP_ZERO) >= 0; diff --git a/js/ref/jsinterp.c b/js/ref/jsinterp.c index 8873a00c111..08d91f936bd 100644 --- a/js/ref/jsinterp.c +++ b/js/ref/jsinterp.c @@ -140,7 +140,6 @@ static JSClass prop_iterator_class = { jsint _i; \ jsval _v; \ \ - _i = (jsint)d; \ if (JSDOUBLE_IS_INT(d, _i) && INT_FITS_IN_JSVAL(_i)) { \ _v = INT_TO_JSVAL(_i); \ } else { \ diff --git a/js/ref/jsnum.c b/js/ref/jsnum.c index a887f9a5804..376e144c4e7 100644 --- a/js/ref/jsnum.c +++ b/js/ref/jsnum.c @@ -393,7 +393,6 @@ js_NewNumberValue(JSContext *cx, jsdouble d, jsval *rval) { jsint i; - i = (jsint)d; if (JSDOUBLE_IS_INT(d, i) && INT_FITS_IN_JSVAL(i)) { *rval = INT_TO_JSVAL(i); } else { @@ -427,7 +426,6 @@ js_NumberToString(JSContext *cx, jsdouble d) jsint i; char buf[32]; - i = (jsint)d; if (JSDOUBLE_IS_INT(d, i)) { PR_snprintf(buf, sizeof buf, "%ld", (long)i); } else { diff --git a/js/ref/jsnum.h b/js/ref/jsnum.h index 626a6b478ad..bee89f49dd3 100644 --- a/js/ref/jsnum.h +++ b/js/ref/jsnum.h @@ -57,14 +57,14 @@ PR_BEGIN_EXTERN_C #define JSDOUBLE_IS_NEGZERO(d) (JSDOUBLE_HI32(d) == JSDOUBLE_HI32_SIGNBIT && \ JSDOUBLE_LO32(d) == 0) -#define JSDOUBLE_IS_INT_2(d, i) (!JSDOUBLE_IS_NEGZERO(d) && (jsdouble)i == d) - -#ifdef XP_PC -/* XXX MSVC miscompiles NaN floating point comparisons for ==, !=, <, and <= */ -#define JSDOUBLE_IS_INT(d, i) (!JSDOUBLE_IS_NaN(d) && JSDOUBLE_IS_INT_2(d, i)) -#else -#define JSDOUBLE_IS_INT(d, i) JSDOUBLE_IS_INT_2(d, i) -#endif +/* + * JSDOUBLE_IS_INT first checks that d is neither NaN nor infinite, to avoid + * raising SIGFPE on platforms such as Alpha Linux, then (only if the cast is + * safe) leaves i as (jsint)d. This also avoid anomalous NaN floating point + * comparisons under MSVC. + */ +#define JSDOUBLE_IS_INT(d, i) (JSDOUBLE_IS_FINITE(d) && !JSDOUBLE_IS_NEGZERO(d) \ + && ((d) == (i = (jsint)(d)))) /* Initialize the Number class, returning its prototype object. */ extern JSObject *