bug=421154 r=brendan a1.9=blockin1.9 Faster number conversions

This commit is contained in:
igor@mir2.org 2008-03-06 15:24:08 -08:00
Родитель d244cc0126
Коммит f94c50c5ff
14 изменённых файлов: 292 добавлений и 207 удалений

Просмотреть файл

@ -203,7 +203,7 @@ JS_ConvertArgumentsVA(JSContext *cx, uintN argc, jsval *argv,
*va_arg(ap, JSBool *) = js_ValueToBoolean(*sp);
break;
case 'c':
if (!js_ValueToUint16(cx, *sp, va_arg(ap, uint16 *)))
if (!JS_ValueToUint16(cx, *sp, va_arg(ap, uint16 *)))
return JS_FALSE;
break;
case 'i':
@ -215,15 +215,15 @@ JS_ConvertArgumentsVA(JSContext *cx, uintN argc, jsval *argv,
return JS_FALSE;
break;
case 'j':
if (!js_ValueToInt32(cx, *sp, va_arg(ap, int32 *)))
if (!JS_ValueToInt32(cx, *sp, va_arg(ap, int32 *)))
return JS_FALSE;
break;
case 'd':
if (!js_ValueToNumber(cx, *sp, va_arg(ap, jsdouble *)))
if (!JS_ValueToNumber(cx, *sp, va_arg(ap, jsdouble *)))
return JS_FALSE;
break;
case 'I':
if (!js_ValueToNumber(cx, *sp, &d))
if (!JS_ValueToNumber(cx, *sp, &d))
return JS_FALSE;
*va_arg(ap, jsdouble *) = js_DoubleToInteger(d);
break;
@ -487,7 +487,7 @@ JS_ConvertValue(JSContext *cx, jsval v, JSType type, jsval *vp)
*vp = STRING_TO_JSVAL(str);
break;
case JSTYPE_NUMBER:
ok = js_ValueToNumber(cx, v, &d);
ok = JS_ValueToNumber(cx, v, &d);
if (ok) {
dp = js_NewDouble(cx, d);
ok = (dp != NULL);
@ -541,8 +541,13 @@ JS_ValueToString(JSContext *cx, jsval v)
JS_PUBLIC_API(JSBool)
JS_ValueToNumber(JSContext *cx, jsval v, jsdouble *dp)
{
JSTempValueRooter tvr;
CHECK_REQUEST(cx);
return js_ValueToNumber(cx, v, dp);
JS_PUSH_SINGLE_TEMP_ROOT(cx, v, &tvr);
*dp = js_ValueToNumber(cx, &tvr.u.value);
JS_POP_TEMP_ROOT(cx, &tvr);
return !JSVAL_IS_NULL(tvr.u.value);
}
JS_PUBLIC_API(JSBool)
@ -554,7 +559,7 @@ JS_ValueToECMAInt32(JSContext *cx, jsval v, int32 *ip)
JS_PUSH_SINGLE_TEMP_ROOT(cx, v, &tvr);
*ip = js_ValueToECMAInt32(cx, &tvr.u.value);
JS_POP_TEMP_ROOT(cx, &tvr);
return tvr.u.value != JSVAL_NULL;
return !JSVAL_IS_NULL(tvr.u.value);
}
JS_PUBLIC_API(JSBool)
@ -566,21 +571,31 @@ JS_ValueToECMAUint32(JSContext *cx, jsval v, uint32 *ip)
JS_PUSH_SINGLE_TEMP_ROOT(cx, v, &tvr);
*ip = js_ValueToECMAUint32(cx, &tvr.u.value);
JS_POP_TEMP_ROOT(cx, &tvr);
return tvr.u.value != JSVAL_NULL;
return !JSVAL_IS_NULL(tvr.u.value);
}
JS_PUBLIC_API(JSBool)
JS_ValueToInt32(JSContext *cx, jsval v, int32 *ip)
{
JSTempValueRooter tvr;
CHECK_REQUEST(cx);
return js_ValueToInt32(cx, v, ip);
JS_PUSH_SINGLE_TEMP_ROOT(cx, v, &tvr);
*ip = js_ValueToInt32(cx, &tvr.u.value);
JS_POP_TEMP_ROOT(cx, &tvr);
return !JSVAL_IS_NULL(tvr.u.value);
}
JS_PUBLIC_API(JSBool)
JS_ValueToUint16(JSContext *cx, jsval v, uint16 *ip)
{
JSTempValueRooter tvr;
CHECK_REQUEST(cx);
return js_ValueToUint16(cx, v, ip);
JS_PUSH_SINGLE_TEMP_ROOT(cx, v, &tvr);
*ip = js_ValueToUint16(cx, &tvr.u.value);
JS_POP_TEMP_ROOT(cx, &tvr);
return !JSVAL_IS_NULL(tvr.u.value);
}
JS_PUBLIC_API(JSBool)

Просмотреть файл

@ -184,37 +184,36 @@ js_IdIsIndex(jsval id, jsuint *indexp)
return JS_FALSE;
}
static JSBool
ValueIsLength(JSContext *cx, jsval v, jsuint *lengthp)
static jsuint
ValueIsLength(JSContext *cx, jsval* vp)
{
jsint i;
jsdouble d;
jsuint length;
if (JSVAL_IS_INT(v)) {
i = JSVAL_TO_INT(v);
if (i < 0) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
JSMSG_BAD_ARRAY_LENGTH);
return JS_FALSE;
}
*lengthp = (jsuint) i;
return JS_TRUE;
if (JSVAL_IS_INT(*vp)) {
i = JSVAL_TO_INT(*vp);
if (i < 0)
goto error;
return (jsuint) i;
}
if (!js_ValueToNumber(cx, v, &d)) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
JSMSG_BAD_ARRAY_LENGTH);
return JS_FALSE;
}
d = js_ValueToNumber(cx, vp);
if (JSVAL_IS_NULL(*vp))
goto error;
*lengthp = js_DoubleToECMAUint32(d);
if (JSDOUBLE_IS_NaN(d))
goto error;
length = (jsuint) d;
if (d != (jsdouble) length)
goto error;
return length;
if (JSDOUBLE_IS_NaN(d) || d != *lengthp) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
JSMSG_BAD_ARRAY_LENGTH);
return JS_FALSE;
}
return JS_TRUE;
error:
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
JSMSG_BAD_ARRAY_LENGTH);
*vp = JSVAL_NULL;
return 0;
}
JSBool
@ -239,7 +238,7 @@ js_GetLengthProperty(JSContext *cx, JSObject *obj, jsuint *lengthp)
*lengthp = (jsuint)i; /* jsuint cast does ToUint32 */
} else {
*lengthp = js_ValueToECMAUint32(cx, &tvr.u.value);
ok = (tvr.u.value != JSVAL_NULL);
ok = !JSVAL_IS_NULL(tvr.u.value);
}
}
JS_POP_TEMP_ROOT(cx, &tvr);
@ -520,8 +519,10 @@ js_HasLengthProperty(JSContext *cx, JSObject *obj, jsuint *lengthp)
id = ATOM_TO_JSID(cx->runtime->atomState.lengthAtom);
ok = OBJ_GET_PROPERTY(cx, obj, id, &tvr.u.value);
JS_SetErrorReporter(cx, older);
if (ok)
ok = ValueIsLength(cx, tvr.u.value, lengthp);
if (ok) {
*lengthp = ValueIsLength(cx, &tvr.u.value);
ok = !JSVAL_IS_NULL(tvr.u.value);
}
JS_POP_TEMP_ROOT(cx, &tvr);
return ok;
}
@ -579,7 +580,8 @@ array_length_setter(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
JSPROP_ENUMERATE, NULL);
}
if (!ValueIsLength(cx, *vp, &newlen))
newlen = ValueIsLength(cx, vp);
if (JSVAL_IS_NULL(*vp))
return JS_FALSE;
oldlen = obj->fslots[JSSLOT_ARRAY_LENGTH];
@ -1725,10 +1727,12 @@ sort_compare(void *arg, const void *a, const void *b, int *result)
*sp++ = av;
*sp++ = bv;
if (!js_Invoke(cx, 2, invokevp, JSINVOKE_INTERNAL) ||
!js_ValueToNumber(cx, *invokevp, &cmp)) {
if (!js_Invoke(cx, 2, invokevp, JSINVOKE_INTERNAL))
return JS_FALSE;
cmp = js_ValueToNumber(cx, invokevp);
if (JSVAL_IS_NULL(*invokevp))
return JS_FALSE;
}
/* Clamp cmp to -1, 0, 1. */
*result = 0;
@ -2231,7 +2235,8 @@ array_splice(JSContext *cx, uintN argc, jsval *vp)
return JS_FALSE;
/* Convert the first argument into a starting index. */
if (!js_ValueToNumber(cx, *argv, &d))
d = js_ValueToNumber(cx, argv);
if (JSVAL_IS_NULL(*argv))
return JS_FALSE;
d = js_DoubleToInteger(d);
if (d < 0) {
@ -2251,7 +2256,8 @@ array_splice(JSContext *cx, uintN argc, jsval *vp)
count = delta;
end = length;
} else {
if (!js_ValueToNumber(cx, *argv, &d))
d = js_ValueToNumber(cx, argv);
if (JSVAL_IS_NULL(*argv))
return JS_FALSE;
d = js_DoubleToInteger(d);
if (d < 0)
@ -2398,7 +2404,8 @@ array_concat(JSContext *cx, uintN argc, jsval *vp)
&tvr.u.value);
if (!ok)
goto out;
ok = ValueIsLength(cx, tvr.u.value, &alength);
alength = ValueIsLength(cx, &tvr.u.value);
ok = !JSVAL_IS_NULL(tvr.u.value);
if (!ok)
goto out;
for (slot = 0; slot < alength; slot++) {
@ -2456,7 +2463,8 @@ array_slice(JSContext *cx, uintN argc, jsval *vp)
end = length;
if (argc > 0) {
if (!js_ValueToNumber(cx, argv[0], &d))
d = js_ValueToNumber(cx, &argv[0]);
if (JSVAL_IS_NULL(argv[0]))
return JS_FALSE;
d = js_DoubleToInteger(d);
if (d < 0) {
@ -2469,7 +2477,8 @@ array_slice(JSContext *cx, uintN argc, jsval *vp)
begin = (jsuint)d;
if (argc > 1) {
if (!js_ValueToNumber(cx, argv[1], &d))
d = js_ValueToNumber(cx, &argv[1]);
if (JSVAL_IS_NULL(argv[1]))
return JS_FALSE;
d = js_DoubleToInteger(d);
if (d < 0) {
@ -2542,7 +2551,8 @@ array_indexOfHelper(JSContext *cx, JSBool isLast, uintN argc, jsval *vp)
} else {
jsdouble start;
if (!js_ValueToNumber(cx, vp[3], &start))
start = js_ValueToNumber(cx, &vp[3]);
if (JSVAL_IS_NULL(vp[3]))
return JS_FALSE;
start = js_DoubleToInteger(start);
if (start < 0) {
@ -2902,7 +2912,8 @@ Array(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
length = 1;
vector = argv;
} else {
if (!ValueIsLength(cx, argv[0], &length))
length = ValueIsLength(cx, &argv[0]);
if (JSVAL_IS_NULL(argv[0]))
return JS_FALSE;
vector = NULL;
}

Просмотреть файл

@ -573,7 +573,8 @@ date_msecFromArgs(JSContext *cx, uintN argc, jsval *argv, jsdouble *rval)
for (loop = 0; loop < MAXARGS; loop++) {
if (loop < argc) {
if (!js_ValueToNumber(cx, argv[loop], &d))
d = js_ValueToNumber(cx, &argv[loop]);
if (JSVAL_IS_NULL(argv[loop]))
return JS_FALSE;
/* return NaN if any arg is not finite */
if (!JSDOUBLE_IS_FINITE(d)) {
@ -1262,7 +1263,8 @@ date_setTime(JSContext *cx, uintN argc, jsval *vp)
{
jsdouble result;
if (!js_ValueToNumber(cx, vp[2], &result))
result = js_ValueToNumber(cx, &vp[2]);
if (JSVAL_IS_NULL(vp[2]))
return JS_FALSE;
result = TIMECLIP(result);
@ -1311,7 +1313,8 @@ date_makeTime(JSContext *cx, uintN maxargs, JSBool local, uintN argc, jsval *vp)
argv = vp + 2;
for (i = 0; i < argc; i++) {
if (!js_ValueToNumber(cx, argv[i], &args[i]))
args[i] = js_ValueToNumber(cx, &argv[i]);
if (JSVAL_IS_NULL(argv[i]))
return JS_FALSE;
if (!JSDOUBLE_IS_FINITE(args[i])) {
if (!SetUTCTimePtr(cx, obj, NULL, cx->runtime->jsNaN))
@ -1438,7 +1441,8 @@ date_makeDate(JSContext *cx, uintN maxargs, JSBool local, uintN argc, jsval *vp)
argv = vp + 2;
for (i = 0; i < argc; i++) {
if (!js_ValueToNumber(cx, argv[i], &args[i]))
args[i] = js_ValueToNumber(cx, &argv[i]);
if (JSVAL_IS_NULL(argv[i]))
return JS_FALSE;
if (!JSDOUBLE_IS_FINITE(args[i])) {
if (!SetUTCTimePtr(cx, obj, NULL, cx->runtime->jsNaN))
@ -1538,7 +1542,8 @@ date_setYear(JSContext *cx, uintN argc, jsval *vp)
if (!GetUTCTime(cx, obj, vp, &result))
return JS_FALSE;
if (!js_ValueToNumber(cx, vp[2], &year))
year = js_ValueToNumber(cx, &vp[2]);
if (JSVAL_IS_NULL(vp[2]))
return JS_FALSE;
if (!JSDOUBLE_IS_FINITE(year)) {
if (!SetUTCTimePtr(cx, obj, NULL, cx->runtime->jsNaN))
@ -2071,7 +2076,8 @@ Date(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
} else if (argc == 1) {
if (!JSVAL_IS_STRING(argv[0])) {
/* the argument is a millisecond number */
if (!js_ValueToNumber(cx, argv[0], &d))
d = js_ValueToNumber(cx, &argv[0]);
if (JSVAL_IS_NULL(argv[0]))
return JS_FALSE;
date = date_constructor(cx, obj);
if (!date)

Просмотреть файл

@ -794,7 +794,7 @@ Exception(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
/* Set the 'lineNumber' property. */
if (argc > 2) {
lineno = js_ValueToECMAUint32(cx, &argv[2]);
if (argv[2] == JSVAL_NULL)
if (JSVAL_IS_NULL(argv[2]))
return JS_FALSE;
} else {
if (!fp)
@ -914,7 +914,7 @@ exn_toSource(JSContext *cx, uintN argc, jsval *vp)
if (!ok)
goto out;
lineno = js_ValueToECMAUint32 (cx, &localroots[2]);
ok = (localroots[2] != JSVAL_NULL);
ok = !JSVAL_IS_NULL(localroots[2]);
if (!ok)
goto out;
@ -1344,7 +1344,7 @@ js_ReportUncaughtException(JSContext *cx)
if (!ok)
goto out;
lineno = js_ValueToECMAUint32 (cx, &roots[4]);
ok = (roots[4] != JSVAL_NULL);
ok = !JSVAL_IS_NULL(roots[4]);
if (!ok)
goto out;

Просмотреть файл

@ -1456,7 +1456,7 @@ fun_toStringHelper(JSContext *cx, uint32 indent, uintN argc, jsval *vp)
obj = JSVAL_TO_OBJECT(fval);
if (argc != 0) {
indent = js_ValueToECMAUint32(cx, &vp[2]);
if (vp[2] == JSVAL_NULL)
if (JSVAL_IS_NULL(vp[2]))
return JS_FALSE;
}

Просмотреть файл

@ -2022,7 +2022,8 @@ js_DoIncDec(JSContext *cx, const JSCodeSpec *cs, jsval *vp, jsval *vp2)
} else if (JSVAL_IS_INT(v)) {
d = JSVAL_TO_INT(v);
} else {
if (!js_ValueToNumber(cx, v, &d))
d = js_ValueToNumber(cx, vp);
if (JSVAL_IS_NULL(*vp))
return JS_FALSE;
/* Store the result of v conversion back in vp for post increments. */
@ -2255,7 +2256,7 @@ js_DumpOpMeters()
jsval v_; \
\
v_ = FETCH_OPND(n); \
VALUE_TO_NUMBER(cx, v_, d); \
VALUE_TO_NUMBER(cx, n, v_, d); \
JS_END_MACRO
#define FETCH_INT(cx, n, i) \
@ -2268,7 +2269,7 @@ js_DumpOpMeters()
} else { \
SAVE_SP_AND_PC(fp); \
i = js_ValueToECMAInt32(cx, &sp[n]); \
if (sp[n] == JSVAL_NULL) \
if (JSVAL_IS_NULL(sp[n])) \
goto error; \
} \
JS_END_MACRO
@ -2283,7 +2284,7 @@ js_DumpOpMeters()
} else { \
SAVE_SP_AND_PC(fp); \
ui = js_ValueToECMAUint32(cx, &sp[n]); \
if (sp[n] == JSVAL_NULL) \
if (JSVAL_IS_NULL(sp[n])) \
goto error; \
} \
JS_END_MACRO
@ -2292,15 +2293,17 @@ js_DumpOpMeters()
* Optimized conversion macros that test for the desired type in v before
* homing sp and calling a conversion function.
*/
#define VALUE_TO_NUMBER(cx, v, d) \
#define VALUE_TO_NUMBER(cx, n, v, d) \
JS_BEGIN_MACRO \
JS_ASSERT(v == sp[n]); \
if (JSVAL_IS_INT(v)) { \
d = (jsdouble)JSVAL_TO_INT(v); \
} else if (JSVAL_IS_DOUBLE(v)) { \
d = *JSVAL_TO_DOUBLE(v); \
} else { \
SAVE_SP_AND_PC(fp); \
if (!js_ValueToNumber(cx, v, &d)) \
d = js_ValueToNumber(cx, &sp[n]); \
if (JSVAL_IS_NULL(sp[n])) \
goto error; \
} \
JS_END_MACRO
@ -3448,8 +3451,8 @@ interrupt:
str2 = JSVAL_TO_STRING(rval); \
cond = js_CompareStrings(str, str2) OP 0; \
} else { \
VALUE_TO_NUMBER(cx, lval, d); \
VALUE_TO_NUMBER(cx, rval, d2); \
VALUE_TO_NUMBER(cx, -2, lval, d); \
VALUE_TO_NUMBER(cx, -1, rval, d2); \
cond = JSDOUBLE_COMPARE(d, OP, d2, JS_FALSE); \
} \
} \
@ -3537,8 +3540,8 @@ interrupt:
str2 = JSVAL_TO_STRING(rval); \
cond = js_EqualStrings(str, str2) OP JS_TRUE; \
} else { \
VALUE_TO_NUMBER(cx, lval, d); \
VALUE_TO_NUMBER(cx, rval, d2); \
VALUE_TO_NUMBER(cx, -2, lval, d); \
VALUE_TO_NUMBER(cx, -1, rval, d2); \
cond = JSDOUBLE_COMPARE(d, OP, d2, IFNAN); \
} \
} \
@ -3628,7 +3631,7 @@ interrupt:
} else { \
SAVE_SP_AND_PC(fp); \
shift = js_ValueToECMAInt32(cx, &sp[-1]); \
if (sp[-1] == JSVAL_NULL) \
if (JSVAL_IS_NULL(sp[-1])) \
goto error; \
} \
shift &= 31; \
@ -3709,8 +3712,8 @@ interrupt:
sp--;
STORE_OPND(-1, STRING_TO_JSVAL(str));
} else {
VALUE_TO_NUMBER(cx, lval, d);
VALUE_TO_NUMBER(cx, rval, d2);
VALUE_TO_NUMBER(cx, -2, lval, d);
VALUE_TO_NUMBER(cx, -1, rval, d2);
d += d2;
sp--;
STORE_NUMBER(cx, -1, d);
@ -3797,12 +3800,16 @@ interrupt:
i = -i;
JS_ASSERT(INT_FITS_IN_JSVAL(i));
rval = INT_TO_JSVAL(i);
STORE_OPND(-1, rval);
} else {
SAVE_SP_AND_PC(fp);
if (JSVAL_IS_DOUBLE(rval))
if (JSVAL_IS_DOUBLE(rval)) {
d = *JSVAL_TO_DOUBLE(rval);
else if (!js_ValueToNumber(cx, rval, &d))
goto error;
} else {
d = js_ValueToNumber(cx, &sp[-1]);
if (JSVAL_IS_NULL(sp[-1]))
goto error;
}
#ifdef HPUX
/*
* Negation of a zero doesn't produce a negative
@ -3813,21 +3820,20 @@ interrupt:
#else
d = -d;
#endif
if (!js_NewNumberValue(cx, d, &rval))
if (!js_NewNumberValue(cx, d, &sp[-1]))
goto error;
}
STORE_OPND(-1, rval);
END_CASE(JSOP_NEG)
BEGIN_CASE(JSOP_POS)
rval = FETCH_OPND(-1);
if (!JSVAL_IS_NUMBER(rval)) {
SAVE_SP_AND_PC(fp);
if (!js_ValueToNumber(cx, rval, &d))
d = js_ValueToNumber(cx, &sp[-1]);
if (JSVAL_IS_NULL(sp[-1]))
goto error;
if (!js_NewNumberValue(cx, d, &rval))
if (!js_NewNumberValue(cx, d, &sp[-1]))
goto error;
sp[-1] = rval;
}
END_CASE(JSOP_POS)

Просмотреть файл

@ -105,7 +105,8 @@ math_abs(JSContext *cx, uintN argc, jsval *vp)
{
jsdouble x, z;
if (!js_ValueToNumber(cx, vp[2], &x))
x = js_ValueToNumber(cx, &vp[2]);
if (JSVAL_IS_NULL(vp[2]))
return JS_FALSE;
z = fd_fabs(x);
return js_NewNumberValue(cx, z, vp);
@ -116,7 +117,8 @@ math_acos(JSContext *cx, uintN argc, jsval *vp)
{
jsdouble x, z;
if (!js_ValueToNumber(cx, vp[2], &x))
x = js_ValueToNumber(cx, &vp[2]);
if (JSVAL_IS_NULL(vp[2]))
return JS_FALSE;
z = fd_acos(x);
return js_NewNumberValue(cx, z, vp);
@ -127,7 +129,8 @@ math_asin(JSContext *cx, uintN argc, jsval *vp)
{
jsdouble x, z;
if (!js_ValueToNumber(cx, vp[2], &x))
x = js_ValueToNumber(cx, &vp[2]);
if (JSVAL_IS_NULL(vp[2]))
return JS_FALSE;
z = fd_asin(x);
return js_NewNumberValue(cx, z, vp);
@ -138,7 +141,8 @@ math_atan(JSContext *cx, uintN argc, jsval *vp)
{
jsdouble x, z;
if (!js_ValueToNumber(cx, vp[2], &x))
x = js_ValueToNumber(cx, &vp[2]);
if (JSVAL_IS_NULL(vp[2]))
return JS_FALSE;
z = fd_atan(x);
return js_NewNumberValue(cx, z, vp);
@ -149,9 +153,11 @@ math_atan2(JSContext *cx, uintN argc, jsval *vp)
{
jsdouble x, y, z;
if (!js_ValueToNumber(cx, vp[2], &x))
x = js_ValueToNumber(cx, &vp[2]);
if (JSVAL_IS_NULL(vp[2]))
return JS_FALSE;
if (!js_ValueToNumber(cx, vp[3], &y))
y = js_ValueToNumber(cx, &vp[3]);
if (JSVAL_IS_NULL(vp[3]))
return JS_FALSE;
#if !JS_USE_FDLIBM_MATH && defined(_MSC_VER)
/*
@ -177,7 +183,8 @@ math_ceil(JSContext *cx, uintN argc, jsval *vp)
{
jsdouble x, z;
if (!js_ValueToNumber(cx, vp[2], &x))
x = js_ValueToNumber(cx, &vp[2]);
if (JSVAL_IS_NULL(vp[2]))
return JS_FALSE;
z = fd_ceil(x);
return js_NewNumberValue(cx, z, vp);
@ -188,7 +195,8 @@ math_cos(JSContext *cx, uintN argc, jsval *vp)
{
jsdouble x, z;
if (!js_ValueToNumber(cx, vp[2], &x))
x = js_ValueToNumber(cx, &vp[2]);
if (JSVAL_IS_NULL(vp[2]))
return JS_FALSE;
z = fd_cos(x);
return js_NewNumberValue(cx, z, vp);
@ -199,7 +207,8 @@ math_exp(JSContext *cx, uintN argc, jsval *vp)
{
jsdouble x, z;
if (!js_ValueToNumber(cx, vp[2], &x))
x = js_ValueToNumber(cx, &vp[2]);
if (JSVAL_IS_NULL(vp[2]))
return JS_FALSE;
#ifdef _WIN32
if (!JSDOUBLE_IS_NaN(x)) {
@ -222,7 +231,8 @@ math_floor(JSContext *cx, uintN argc, jsval *vp)
{
jsdouble x, z;
if (!js_ValueToNumber(cx, vp[2], &x))
x = js_ValueToNumber(cx, &vp[2]);
if (JSVAL_IS_NULL(vp[2]))
return JS_FALSE;
z = fd_floor(x);
return js_NewNumberValue(cx, z, vp);
@ -233,7 +243,8 @@ math_log(JSContext *cx, uintN argc, jsval *vp)
{
jsdouble x, z;
if (!js_ValueToNumber(cx, vp[2], &x))
x = js_ValueToNumber(cx, &vp[2]);
if (JSVAL_IS_NULL(vp[2]))
return JS_FALSE;
z = fd_log(x);
return js_NewNumberValue(cx, z, vp);
@ -252,7 +263,8 @@ math_max(JSContext *cx, uintN argc, jsval *vp)
}
argv = vp + 2;
for (i = 0; i < argc; i++) {
if (!js_ValueToNumber(cx, argv[i], &x))
x = js_ValueToNumber(cx, &argv[i]);
if (JSVAL_IS_NULL(argv[i]))
return JS_FALSE;
if (JSDOUBLE_IS_NaN(x)) {
*vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
@ -279,7 +291,8 @@ math_min(JSContext *cx, uintN argc, jsval *vp)
}
argv = vp + 2;
for (i = 0; i < argc; i++) {
if (!js_ValueToNumber(cx, argv[i], &x))
x = js_ValueToNumber(cx, &argv[i]);
if (JSVAL_IS_NULL(argv[i]))
return JS_FALSE;
if (JSDOUBLE_IS_NaN(x)) {
*vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
@ -298,9 +311,11 @@ math_pow(JSContext *cx, uintN argc, jsval *vp)
{
jsdouble x, y, z;
if (!js_ValueToNumber(cx, vp[2], &x))
x = js_ValueToNumber(cx, &vp[2]);
if (JSVAL_IS_NULL(vp[2]))
return JS_FALSE;
if (!js_ValueToNumber(cx, vp[3], &y))
y = js_ValueToNumber(cx, &vp[3]);
if (JSVAL_IS_NULL(vp[3]))
return JS_FALSE;
#if !JS_USE_FDLIBM_MATH
/*
@ -428,7 +443,8 @@ math_round(JSContext *cx, uintN argc, jsval *vp)
{
jsdouble x, z;
if (!js_ValueToNumber(cx, vp[2], &x))
x = js_ValueToNumber(cx, &vp[2]);
if (JSVAL_IS_NULL(vp[2]))
return JS_FALSE;
z = fd_copysign(fd_floor(x + 0.5), x);
return js_NewNumberValue(cx, z, vp);
@ -439,7 +455,8 @@ math_sin(JSContext *cx, uintN argc, jsval *vp)
{
jsdouble x, z;
if (!js_ValueToNumber(cx, vp[2], &x))
x = js_ValueToNumber(cx, &vp[2]);
if (JSVAL_IS_NULL(vp[2]))
return JS_FALSE;
z = fd_sin(x);
return js_NewNumberValue(cx, z, vp);
@ -450,7 +467,8 @@ math_sqrt(JSContext *cx, uintN argc, jsval *vp)
{
jsdouble x, z;
if (!js_ValueToNumber(cx, vp[2], &x))
x = js_ValueToNumber(cx, &vp[2]);
if (JSVAL_IS_NULL(vp[2]))
return JS_FALSE;
z = fd_sqrt(x);
return js_NewNumberValue(cx, z, vp);
@ -461,7 +479,8 @@ math_tan(JSContext *cx, uintN argc, jsval *vp)
{
jsdouble x, z;
if (!js_ValueToNumber(cx, vp[2], &x))
x = js_ValueToNumber(cx, &vp[2]);
if (JSVAL_IS_NULL(vp[2]))
return JS_FALSE;
z = fd_tan(x);
return js_NewNumberValue(cx, z, vp);

Просмотреть файл

@ -71,7 +71,8 @@ num_isNaN(JSContext *cx, uintN argc, jsval *vp)
{
jsdouble x;
if (!js_ValueToNumber(cx, vp[2], &x))
x = js_ValueToNumber(cx, &vp[2]);
if (JSVAL_IS_NULL(vp[2]))
return JS_FALSE;
*vp = BOOLEAN_TO_JSVAL(JSDOUBLE_IS_NaN(x));
return JS_TRUE;
@ -82,7 +83,8 @@ num_isFinite(JSContext *cx, uintN argc, jsval *vp)
{
jsdouble x;
if (!js_ValueToNumber(cx, vp[2], &x))
x = js_ValueToNumber(cx, &vp[2]);
if (JSVAL_IS_NULL(vp[2]))
return JS_FALSE;
*vp = BOOLEAN_TO_JSVAL(JSDOUBLE_IS_FINITE(x));
return JS_TRUE;
@ -119,7 +121,7 @@ num_parseInt(JSContext *cx, uintN argc, jsval *vp)
if (argc > 1) {
radix = js_ValueToECMAInt32(cx, &vp[3]);
if (vp[3] == JSVAL_NULL)
if (JSVAL_IS_NULL(vp[3]))
return JS_FALSE;
} else {
radix = 0;
@ -177,7 +179,8 @@ Number(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
jsval v;
if (argc != 0) {
if (!js_ValueToNumber(cx, argv[0], &d))
d = js_ValueToNumber(cx, &argv[0]);
if (JSVAL_IS_NULL(argv[0]))
return JS_FALSE;
} else {
d = 0.0;
@ -264,7 +267,7 @@ num_toString(JSContext *cx, uintN argc, jsval *vp)
base = 10;
if (argc != 0 && !JSVAL_IS_VOID(vp[2])) {
base = js_ValueToECMAInt32(cx, &vp[2]);
if (vp[2] == JSVAL_NULL)
if (JSVAL_IS_NULL(vp[2]))
return JS_FALSE;
if (base < 2 || base > 36) {
char numBuf[12];
@ -431,7 +434,8 @@ num_to(JSContext *cx, JSDToStrMode zeroArgMode, JSDToStrMode oneArgMode,
precision = 0.0;
oneArgMode = zeroArgMode;
} else {
if (!js_ValueToNumber(cx, vp[2], &precision))
precision = js_ValueToNumber(cx, &vp[2]);
if (JSVAL_IS_NULL(vp[2]))
return JS_FALSE;
precision = js_DoubleToInteger(precision);
if (precision < precisionMin || precision > precisionMax) {
@ -728,49 +732,73 @@ js_NumberToString(JSContext *cx, jsdouble d)
return JS_NewStringCopyZ(cx, numStr);
}
JSBool
js_ValueToNumber(JSContext *cx, jsval v, jsdouble *dp)
jsdouble
js_ValueToNumber(JSContext *cx, jsval *vp)
{
JSObject *obj;
jsval v;
JSString *str;
const jschar *bp, *end, *ep;
jsdouble d;
JSObject *obj;
JSTempValueRooter tvr;
if (JSVAL_IS_OBJECT(v)) {
obj = JSVAL_TO_OBJECT(v);
if (!obj) {
*dp = 0;
return JS_TRUE;
v = *vp;
for (;;) {
if (JSVAL_IS_INT(v))
return (jsdouble) JSVAL_TO_INT(v);
if (JSVAL_IS_DOUBLE(v))
return *JSVAL_TO_DOUBLE(v);
if (JSVAL_IS_STRING(v)) {
str = JSVAL_TO_STRING(v);
/*
* Note that ECMA doesn't treat a string beginning with a '0' as
* an octal number here. This works because all such numbers will
* be interpreted as decimal by js_strtod and will never get
* passed to js_strtointeger (which would interpret them as
* octal).
*/
JSSTRING_CHARS_AND_END(str, bp, end);
if ((!js_strtod(cx, bp, end, &ep, &d) ||
js_SkipWhiteSpace(ep, end) != end) &&
(!js_strtointeger(cx, bp, end, &ep, 0, &d) ||
js_SkipWhiteSpace(ep, end) != end)) {
break;
}
return d;
}
if (!OBJ_DEFAULT_VALUE(cx, obj, JSTYPE_NUMBER, &v))
return JS_FALSE;
}
if (JSVAL_IS_INT(v)) {
*dp = (jsdouble)JSVAL_TO_INT(v);
} else if (JSVAL_IS_DOUBLE(v)) {
*dp = *JSVAL_TO_DOUBLE(v);
} else if (JSVAL_IS_STRING(v)) {
str = JSVAL_TO_STRING(v);
if (JSVAL_IS_BOOLEAN(v))
return JSVAL_TO_BOOLEAN(v) ? 1.0 : 0.0;
if (JSVAL_IS_NULL(v)) {
*vp = JSVAL_ZERO;
return 0.0;
}
if (JSVAL_IS_VOID(v))
break;
JS_ASSERT(!JSVAL_IS_PRIMITIVE(v));
obj = JSVAL_TO_OBJECT(v);
/*
* Note that ECMA doesn't treat a string beginning with a '0' as an
* octal number here. This works because all such numbers will be
* interpreted as decimal by js_strtod and will never get passed to
* js_strtointeger (which would interpret them as octal).
* vp roots obj so we cannot use it as an extra root for
* OBJ_DEFAULT_VALUE result when calling the hook.
*/
JSSTRING_CHARS_AND_END(str, bp, end);
if ((!js_strtod(cx, bp, end, &ep, dp) ||
js_SkipWhiteSpace(ep, end) != end) &&
(!js_strtointeger(cx, bp, end, &ep, 0, dp) ||
js_SkipWhiteSpace(ep, end) != end)) {
goto badstr;
JS_PUSH_SINGLE_TEMP_ROOT(cx, v, &tvr);
if (!OBJ_DEFAULT_VALUE(cx, obj, JSTYPE_NUMBER, &tvr.u.value))
obj = NULL;
else
v = *vp = tvr.u.value;
JS_POP_TEMP_ROOT(cx, &tvr);
if (!obj) {
*vp = JSVAL_NULL;
return 0.0;
}
} else if (JSVAL_IS_BOOLEAN(v)) {
*dp = JSVAL_TO_BOOLEAN(v) ? 1 : 0;
} else {
badstr:
*dp = *cx->runtime->jsNaN;
if (!JSVAL_IS_PRIMITIVE(v))
break;
}
return JS_TRUE;
JS_ASSERT(!JSVAL_IS_NULL(*vp));
return *cx->runtime->jsNaN;
}
int32
@ -785,11 +813,9 @@ js_ValueToECMAInt32(JSContext *cx, jsval *vp)
if (JSVAL_IS_DOUBLE(v)) {
d = *JSVAL_TO_DOUBLE(v);
} else {
if (!js_ValueToNumber(cx, v, &d)) {
*vp = JSVAL_NULL;
d = js_ValueToNumber(cx, vp);
if (JSVAL_IS_NULL(*vp))
return 0;
}
*vp = JSVAL_ZERO;
}
return js_DoubleToECMAInt32(d);
}
@ -826,11 +852,9 @@ js_ValueToECMAUint32(JSContext *cx, jsval *vp)
if (JSVAL_IS_DOUBLE(v)) {
d = *JSVAL_TO_DOUBLE(v);
} else {
if (!js_ValueToNumber(cx, v, &d)) {
*vp = JSVAL_NULL;
d = js_ValueToNumber(cx, vp);
if (JSVAL_IS_NULL(*vp))
return 0;
}
*vp = JSVAL_ZERO;
}
return js_DoubleToECMAUint32(d);
}
@ -864,53 +888,50 @@ js_DoubleToECMAUint32(jsdouble d)
return (uint32) (d >= 0 ? d : d + two32);
}
JSBool
js_ValueToInt32(JSContext *cx, jsval v, int32 *ip)
int32
js_ValueToInt32(JSContext *cx, jsval *vp)
{
jsval v;
jsdouble d;
if (JSVAL_IS_INT(v)) {
*ip = JSVAL_TO_INT(v);
return JS_TRUE;
}
if (!js_ValueToNumber(cx, v, &d))
return JS_FALSE;
v = *vp;
if (JSVAL_IS_INT(v))
return JSVAL_TO_INT(v);
d = js_ValueToNumber(cx, vp);
if (JSVAL_IS_NULL(*vp))
return 0;
if (JSDOUBLE_IS_NaN(d) || d <= -2147483649.0 || 2147483648.0 <= d) {
js_ReportValueError(cx, JSMSG_CANT_CONVERT,
JSDVG_SEARCH_STACK, v, NULL);
return JS_FALSE;
*vp = JSVAL_NULL;
return 0;
}
*ip = (int32)floor(d + 0.5); /* Round to nearest */
return JS_TRUE;
return (int32) floor(d + 0.5); /* Round to nearest */
}
JSBool
js_ValueToUint16(JSContext *cx, jsval v, uint16 *ip)
uint16
js_ValueToUint16(JSContext *cx, jsval *vp)
{
jsdouble d;
jsuint i, m;
JSBool neg;
if (!js_ValueToNumber(cx, v, &d))
return JS_FALSE;
if (d == 0 || !JSDOUBLE_IS_FINITE(d)) {
*ip = 0;
return JS_TRUE;
}
i = (jsuint)d;
if ((jsdouble)i == d) {
*ip = (uint16)i;
return JS_TRUE;
}
d = js_ValueToNumber(cx, vp);
if (JSVAL_IS_NULL(*vp))
return 0;
if (d == 0 || !JSDOUBLE_IS_FINITE(d))
return 0;
i = (jsuint) d;
if ((jsdouble) i == d)
return (uint16) i;
neg = (d < 0);
d = floor(neg ? -d : d);
d = neg ? -d : d;
m = JS_BIT(16);
d = fmod(d, (double)m);
d = fmod(d, (double) m);
if (d < 0)
d += m;
*ip = (uint16) d;
return JS_TRUE;
return (uint16) d;
}
jsdouble

Просмотреть файл

@ -197,16 +197,15 @@ char *
js_NumberToCString(JSContext *cx, jsdouble d, char *buf, size_t bufSize);
/*
* Convert a value to a number, returning false after reporting any error,
* otherwise returning true with *dp set.
* Convert a value to a number. On exit JSVAL_IS_NULL(*vp) iff there was an
* error.
*/
extern JSBool
js_ValueToNumber(JSContext *cx, jsval v, jsdouble *dp);
extern jsdouble
js_ValueToNumber(JSContext *cx, jsval* vp);
/*
* Convert a value to an int32 or uint32, according to the ECMA rules for
* ToInt32 and ToUint32. On failure the functions sets *vp to JSVAL_NULL. Any
* other value in *vp on exit indicates a success.
* ToInt32 and ToUint32. On exit JSVAL_IS_NULL(*vp) iff there was an error.
*/
extern int32
js_ValueToECMAInt32(JSContext *cx, jsval *vp);
@ -223,25 +222,20 @@ js_DoubleToECMAInt32(jsdouble d);
extern uint32
js_DoubleToECMAUint32(jsdouble d);
/*
* Convert a value or a double to a uint32, according to the ECMA rules
* for ToUint32.
*/
/*
* Convert a value to a number, then to an int32 if it fits by rounding to
* nearest; but failing with an error report if the double is out of range
* or unordered.
* or unordered. On exit JSVAL_IS_NULL(*vp) iff there was an error.
*/
extern JSBool
js_ValueToInt32(JSContext *cx, jsval v, int32 *ip);
extern int32
js_ValueToInt32(JSContext *cx, jsval *vp);
/*
* Convert a value to a number, then to a uint16 according to the ECMA rules
* for ToUint16.
* for ToUint16. On exit JSVAL_IS_NULL(*vp) iff there was an error.
*/
extern JSBool
js_ValueToUint16(JSContext *cx, jsval v, uint16 *ip);
extern uint16
js_ValueToUint16(JSContext *cx, jsval *vp);
/*
* Convert a jsdouble to an integral number, stored in a jsdouble.

Просмотреть файл

@ -5897,7 +5897,7 @@ FoldType(JSContext *cx, JSParseNode *pn, JSTokenType type)
case TOK_NUMBER:
if (pn->pn_type == TOK_STRING) {
jsdouble d;
if (!js_ValueToNumber(cx, ATOM_KEY(pn->pn_atom), &d))
if (!JS_ValueToNumber(cx, ATOM_KEY(pn->pn_atom), &d))
return JS_FALSE;
pn->pn_dval = d;
pn->pn_type = TOK_NUMBER;

Просмотреть файл

@ -3646,7 +3646,7 @@ regexp_setProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
return ok;
slot = JSVAL_TO_INT(id);
if (slot == REGEXP_LAST_INDEX) {
if (!js_ValueToNumber(cx, *vp, &lastIndex))
if (!JS_ValueToNumber(cx, *vp, &lastIndex))
return JS_FALSE;
lastIndex = js_DoubleToInteger(lastIndex);
ok = js_NewNumberValue(cx, lastIndex, vp) &&
@ -4321,7 +4321,7 @@ js_GetLastIndex(JSContext *cx, JSObject *obj, jsdouble *lastIndex)
jsval v;
return JS_GetReservedSlot(cx, obj, 0, &v) &&
js_ValueToNumber(cx, v, lastIndex);
JS_ValueToNumber(cx, v, lastIndex);
}
JSBool

Просмотреть файл

@ -112,7 +112,7 @@ script_toSource(JSContext *cx, uintN argc, jsval *vp)
indent = 0;
if (argc != 0) {
indent = js_ValueToECMAUint32(cx, &vp[2]);
if (vp[2] == JSVAL_NULL)
if (JSVAL_IS_NULL(vp[2]))
return JS_FALSE;
}
@ -171,7 +171,7 @@ script_toString(JSContext *cx, uintN argc, jsval *vp)
indent = 0;
if (argc != 0) {
indent = js_ValueToECMAUint32(cx, &vp[2]);
if (vp[2] == JSVAL_NULL)
if (JSVAL_IS_NULL(vp[2]))
return JS_FALSE;
}

Просмотреть файл

@ -312,7 +312,8 @@ js_str_escape(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval
mask = URL_XALPHAS | URL_XPALPHAS | URL_PATH;
if (argc > 1) {
if (!js_ValueToNumber(cx, argv[1], &d))
d = js_ValueToNumber(cx, &argv[1]);
if (JSVAL_IS_NULL(argv[1]))
return JS_FALSE;
if (!JSDOUBLE_IS_FINITE(d) ||
(mask = (jsint)d) != d ||
@ -707,7 +708,8 @@ str_substring(JSContext *cx, uintN argc, jsval *vp)
NORMALIZE_THIS(cx, vp, str);
if (argc != 0) {
if (!js_ValueToNumber(cx, vp[2], &d))
d = js_ValueToNumber(cx, &vp[2]);
if (JSVAL_IS_NULL(vp[2]))
return JS_FALSE;
length = JSSTRING_LENGTH(str);
begin = js_DoubleToInteger(d);
@ -719,7 +721,8 @@ str_substring(JSContext *cx, uintN argc, jsval *vp)
if (argc == 1) {
end = length;
} else {
if (!js_ValueToNumber(cx, vp[3], &d))
d = js_ValueToNumber(cx, &vp[3]);
if (JSVAL_IS_NULL(vp[3]))
return JS_FALSE;
end = js_DoubleToInteger(d);
if (end < 0)
@ -867,7 +870,8 @@ str_charAt(JSContext *cx, uintN argc, jsval *vp)
if (argc == 0) {
d = 0.0;
} else {
if (!js_ValueToNumber(cx, v, &d))
d = js_ValueToNumber(cx, &vp[2]);
if (JSVAL_IS_NULL(vp[2]))
return JS_FALSE;
d = js_DoubleToInteger(d);
}
@ -911,7 +915,8 @@ str_charCodeAt(JSContext *cx, uintN argc, jsval *vp)
if (argc == 0) {
d = 0.0;
} else {
if (!js_ValueToNumber(cx, v, &d))
d = js_ValueToNumber(cx, &vp[2]);
if (JSVAL_IS_NULL(vp[2]))
return JS_FALSE;
d = js_DoubleToInteger(d);
}
@ -992,7 +997,8 @@ str_indexOf(JSContext *cx, uintN argc, jsval *vp)
patlen = (jsint) JSSTRING_LENGTH(str2);
if (argc > 1) {
if (!js_ValueToNumber(cx, vp[3], &d))
d = js_ValueToNumber(cx, &vp[3]);
if (JSVAL_IS_NULL(vp[3]))
return JS_FALSE;
d = js_DoubleToInteger(d);
if (d < 0)
@ -1055,7 +1061,8 @@ str_lastIndexOf(JSContext *cx, uintN argc, jsval *vp)
patlen = (jsint) JSSTRING_LENGTH(str2);
if (argc > 1) {
if (!js_ValueToNumber(cx, vp[3], &d))
d = js_ValueToNumber(cx, &vp[3]);
if (JSVAL_IS_NULL(vp[3]))
return JS_FALSE;
if (JSDOUBLE_IS_NaN(d)) {
i = textlen;
@ -1829,7 +1836,8 @@ str_split(JSContext *cx, uintN argc, jsval *vp)
limited = (argc > 1) && !JSVAL_IS_VOID(vp[3]);
limit = 0; /* Avoid warning. */
if (limited) {
if (!js_ValueToNumber(cx, vp[3], &d))
d = js_ValueToNumber(cx, &vp[3]);
if (JSVAL_IS_NULL(vp[3]))
return JS_FALSE;
/* Clamp limit between 0 and 1 + string length. */
@ -1890,7 +1898,8 @@ str_substr(JSContext *cx, uintN argc, jsval *vp)
NORMALIZE_THIS(cx, vp, str);
if (argc != 0) {
if (!js_ValueToNumber(cx, vp[2], &d))
d = js_ValueToNumber(cx, &vp[2]);
if (JSVAL_IS_NULL(vp[2]))
return JS_FALSE;
length = JSSTRING_LENGTH(str);
begin = js_DoubleToInteger(d);
@ -1905,7 +1914,8 @@ str_substr(JSContext *cx, uintN argc, jsval *vp)
if (argc == 1) {
end = length;
} else {
if (!js_ValueToNumber(cx, vp[3], &d))
d = js_ValueToNumber(cx, &vp[3]);
if (JSVAL_IS_NULL(vp[3]))
return JS_FALSE;
end = js_DoubleToInteger(d);
if (end < 0)
@ -1988,7 +1998,8 @@ str_slice(JSContext *cx, uintN argc, jsval *vp)
if (argc != 0) {
double begin, end, length;
if (!js_ValueToNumber(cx, v, &begin))
begin = js_ValueToNumber(cx, &vp[2]);
if (JSVAL_IS_NULL(vp[2]))
return JS_FALSE;
begin = js_DoubleToInteger(begin);
length = JSSTRING_LENGTH(str);
@ -2003,7 +2014,8 @@ str_slice(JSContext *cx, uintN argc, jsval *vp)
if (argc == 1) {
end = length;
} else {
if (!js_ValueToNumber(cx, vp[3], &end))
end = js_ValueToNumber(cx, &vp[3]);
if (JSVAL_IS_NULL(vp[3]))
return JS_FALSE;
end = js_DoubleToInteger(end);
if (end < 0) {
@ -2279,7 +2291,8 @@ str_fromCharCode(JSContext *cx, uintN argc, jsval *vp)
if (!chars)
return JS_FALSE;
for (i = 0; i < argc; i++) {
if (!js_ValueToUint16(cx, argv[i], &code)) {
code = js_ValueToUint16(cx, &argv[i]);
if (JSVAL_IS_NULL(argv[i])) {
JS_free(cx, chars);
return JS_FALSE;
}

Просмотреть файл

@ -5482,7 +5482,7 @@ xml_equality(JSContext *cx, JSObject *obj, jsval v, JSBool *bp)
} else if (JSVAL_IS_STRING(v)) {
*bp = js_EqualStrings(str, JSVAL_TO_STRING(v));
} else {
ok = js_ValueToNumber(cx, STRING_TO_JSVAL(str), &d);
ok = JS_ValueToNumber(cx, STRING_TO_JSVAL(str), &d);
if (ok) {
d2 = JSVAL_IS_INT(v) ? JSVAL_TO_INT(v)
: *JSVAL_TO_DOUBLE(v);