JS_ReportError(cx, "%s is not a number",
JS_ReportErrorNumber(cx, NULL, JSMSG_NAN,
js_ValueToNumber(JSContext *cx, jsval v, jsdouble *dp){    JSObject *obj;    JSString *str;    const jschar *ep;    jsdouble d;    if (JSVAL_IS_OBJECT(v)) {	obj = JSVAL_TO_OBJECT(v);	if (!obj) {	    *dp = 0;	    return JS_TRUE;	}	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);	errno = 0;	/* Note that ECMAScript doesn't treat numbers beginning with a zero as octal numbers 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. */	if ((!js_strtod(cx, str->chars, &ep, &d) || js_SkipWhiteSpace(ep) != str->chars + str->length) &&	    (!js_strtointeger(cx, str->chars, &ep, 0, &d) || js_SkipWhiteSpace(ep) != str->chars + str->length)) {	    goto badstr;	}	*dp = d;    } else if (JSVAL_IS_BOOLEAN(v)) {	*dp = JSVAL_TO_BOOLEAN(v) ? 1 : 0;    } else {#if JS_BUG_FALLIBLE_TONUM	str = js_DecompileValueGenerator(cx, v, NULL);badstr:	if (str) {	    JS_ReportError(cx, "%s is not a number",			   JS_GetStringBytes(str));	}	return JS_FALSE;#elsebadstr:	*dp = *cx->runtime->jsNaN;#endif    }    return JS_TRUE;}