Bug 503160 - integer constants are not automatically demoted. Patch by Andreas Gal and Robert Sayre. r=dvander/gal

This commit is contained in:
Robert Sayre 2009-07-22 19:47:41 -04:00
parent 9534c3d315
commit b8172c1402
3 changed files with 43 additions and 11 deletions

View File

@ -892,11 +892,10 @@ js_PrototypeHasIndexedProperties(JSContext *cx, JSObject *obj)
}
#ifdef JS_TRACER
JSBool FASTCALL
js_Array_dense_setelem(JSContext* cx, JSObject* obj, jsint i, jsval v)
{
JS_ASSERT(OBJ_IS_DENSE_ARRAY(cx, obj));
static inline JSBool FASTCALL
dense_grow(JSContext* cx, JSObject* obj, jsint i, jsval v)
{
/*
* Let the interpreter worry about negative array indexes.
*/
@ -930,7 +929,33 @@ js_Array_dense_setelem(JSContext* cx, JSObject* obj, jsint i, jsval v)
obj->dslots[u] = v;
return JS_TRUE;
}
JSBool FASTCALL
js_Array_dense_setelem(JSContext* cx, JSObject* obj, jsint i, jsval v)
{
JS_ASSERT(OBJ_IS_DENSE_ARRAY(cx, obj));
return dense_grow(cx, obj, i, v);
}
JS_DEFINE_CALLINFO_4(extern, BOOL, js_Array_dense_setelem, CONTEXT, OBJECT, INT32, JSVAL, 0, 0)
JSBool FASTCALL
js_Array_dense_setelem_int(JSContext* cx, JSObject* obj, jsint i, int32 j)
{
JS_ASSERT(OBJ_IS_DENSE_ARRAY(cx, obj));
jsval v;
if (JS_LIKELY(INT_FITS_IN_JSVAL(j))) {
v = INT_TO_JSVAL(j);
} else {
jsdouble d = (jsdouble)j;
if (!js_NewDoubleInRootedValue(cx, d, &v))
return JS_FALSE;
}
return dense_grow(cx, obj, i, v);
}
JS_DEFINE_CALLINFO_4(extern, BOOL, js_Array_dense_setelem_int, CONTEXT, OBJECT, INT32, INT32, 0, 0)
#endif
static JSBool

View File

@ -435,6 +435,7 @@ JS_DECLARE_CALLINFO(js_NewInstance)
/* Defined in jsarray.cpp. */
JS_DECLARE_CALLINFO(js_Array_dense_setelem)
JS_DECLARE_CALLINFO(js_Array_dense_setelem_int)
JS_DECLARE_CALLINFO(js_NewEmptyArray)
JS_DECLARE_CALLINFO(js_NewUninitializedArray)
JS_DECLARE_CALLINFO(js_ArrayCompPush)

View File

@ -1242,8 +1242,8 @@ public:
} else if (ci == &js_BoxDouble_ci) {
LInsp s0 = args[0];
JS_ASSERT(s0->isQuad());
if (isi2f(s0)) {
LIns* args2[] = { iu2fArg(s0), args[1] };
if (isPromoteInt(s0)) {
LIns* args2[] = { demote(out, s0), args[1] };
return out->insCall(&js_BoxInt32_ci, args2);
}
if (s0->isCall() && s0->callInfo() == &js_UnboxDouble_ci)
@ -9669,12 +9669,18 @@ TraceRecorder::record_JSOP_SETELEM()
idx_ins = makeNumberInt32(idx_ins);
// Box the value so we can use one builtin instead of having to add one builtin for every
// storage type.
LIns* boxed_v_ins = v_ins;
box_jsval(v, boxed_v_ins);
// storage type. Special case for integers though, since they are so common.
LIns* res_ins;
if (isNumber(v) && isPromoteInt(v_ins)) {
LIns* args[] = { ::demote(lir, v_ins), idx_ins, obj_ins, cx_ins };
res_ins = lir->insCall(&js_Array_dense_setelem_int_ci, args);
} else {
LIns* boxed_v_ins = v_ins;
box_jsval(v, boxed_v_ins);
LIns* args[] = { boxed_v_ins, idx_ins, obj_ins, cx_ins };
LIns* res_ins = lir->insCall(&js_Array_dense_setelem_ci, args);
LIns* args[] = { boxed_v_ins, idx_ins, obj_ins, cx_ins };
res_ins = lir->insCall(&js_Array_dense_setelem_ci, args);
}
guard(false, lir->ins_eq0(res_ins), MISMATCH_EXIT);
jsbytecode* pc = cx->fp->regs->pc;