Subj : sm: JS_ValueToInt unexpected results To : netscape.public.mozilla.jseng From : Jens Thiele Date : Sat Jan 08 2005 12:46 pm This is a multi-part message in MIME format. --------------030600040705010201050002 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Hi, JS_ValueToInt32 gives unexpected results (wrap around => negative) for Number values: [2147483647.5, 2147483648[ This is since the rounding is done after the range check: js_ValueToInt32(JSContext *cx, jsval v, int32 *ip) { jsdouble d; JSString *str; if (JSVAL_IS_INT(v)) { *ip = JSVAL_TO_INT(v); return JS_TRUE; } if (!js_ValueToNumber(cx, v, &d)) return JS_FALSE; if (JSDOUBLE_IS_NaN(d) || d <= -2147483649.0 || 2147483648.0 <= d) { str = js_DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, v, NULL); if (str) { JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_CONVERT, JS_GetStringBytes(str)); } return JS_FALSE; } *ip = (int32)floor(d + 0.5); /* Round to nearest */ return JS_TRUE; } Jens attached a test case --------------030600040705010201050002 Content-Type: text/x-csrc; name="test.c" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="test.c" /* get SpiderMonkey API declarations */ #include /* EXIT_FAILURE and EXIT_SUCCESS */ #include /* strlen */ #include int main(int argc, char** argv) { /* pointer to our runtime object */ JSRuntime *runtime=NULL; /* pointer to our context */ JSContext *context=NULL; /* pointer to our global JavaScript object */ JSObject *global=NULL; /* script to run (should preduce an error) */ char *script="2147483647.5"; /* JavaScript value to store the result of the script */ jsval rval; /* create new runtime, new context, global object */ if ( (!(runtime = JS_NewRuntime (1024L*1024L))) || (!(context = JS_NewContext (runtime, 8192))) || (!(global = JS_NewObject (context, NULL, NULL, NULL))) ) return EXIT_FAILURE; /* set global object of context and initialize standard ECMAScript objects (Math, Date, ...) within this global object scope */ if (!JS_InitStandardClasses(context, global)) return EXIT_FAILURE; /* now we are ready to run our script */ if (JS_EvaluateScript(context, global,script, strlen(script), "script", 1, &rval)) return EXIT_FAILURE; /* clean up */ JS_DestroyContext(context); JS_DestroyRuntime(runtime); JS_ShutDown(); return EXIT_SUCCESS; } --------------030600040705010201050002-- .