зеркало из https://github.com/mozilla/pjs.git
Changed the definition of JSDOUBLE_IS_INT(d, i) to delay a (jsint)d
cast until after the double in question has been determined to be finite, not NaN, etc. This may make the code a little more XP for platforms like BSD and Alpha Linux that don't like casting strange values to int. Thanks go to Uncle George <gatgul@voicenet.com> and hankin <hankin@consultco.com> for their porting work.
This commit is contained in:
Родитель
f498bdc88b
Коммит
53b3ff3224
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 { \
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 *
|
||||
|
|
Загрузка…
Ссылка в новой задаче