[INFER] Improve type handler precision for Array.{slic,pop,shift}, bug 642412.

This commit is contained in:
Brian Hackett 2011-03-18 08:17:22 -07:00
parent 537b627fc2
commit 707a3eae96

View File

@ -2222,12 +2222,16 @@ array_pop_slowly(JSContext *cx, JSObject* obj, Value *vp)
return JS_FALSE;
if (index == 0) {
vp->setUndefined();
if (!cx->markTypeCallerUnexpected(TYPE_UNDEFINED))
return JS_FALSE;
} else {
index--;
/* Get the to-be-deleted property's value into vp. */
if (!GetElement(cx, obj, index, &hole, vp))
return JS_FALSE;
if (hole && !cx->markTypeCallerUnexpected(TYPE_UNDEFINED))
return JS_FALSE;
if (!hole && DeleteArrayElement(cx, obj, index, true) < 0)
return JS_FALSE;
}
@ -2243,11 +2247,15 @@ array_pop_dense(JSContext *cx, JSObject* obj, Value *vp)
index = obj->getArrayLength();
if (index == 0) {
vp->setUndefined();
if (!cx->markTypeCallerUnexpected(TYPE_UNDEFINED))
return JS_FALSE;
return JS_TRUE;
}
index--;
if (!GetElement(cx, obj, index, &hole, vp))
return JS_FALSE;
if (hole && !cx->markTypeCallerUnexpected(TYPE_UNDEFINED))
return JS_FALSE;
if (!hole && DeleteArrayElement(cx, obj, index, true) < 0)
return JS_FALSE;
obj->setDenseArrayLength(index);
@ -2280,6 +2288,8 @@ array_shift(JSContext *cx, uintN argc, Value *vp)
if (length == 0) {
vp->setUndefined();
if (!cx->markTypeCallerUnexpected(TYPE_UNDEFINED))
return JS_FALSE;
} else {
length--;
@ -2288,8 +2298,11 @@ array_shift(JSContext *cx, uintN argc, Value *vp)
jsuint initlen = obj->getDenseArrayInitializedLength();
if (initlen > 0) {
*vp = obj->getDenseArrayElement(0);
if (vp->isMagic(JS_ARRAY_HOLE))
if (vp->isMagic(JS_ARRAY_HOLE)) {
vp->setUndefined();
if (!cx->markTypeCallerUnexpected(TYPE_UNDEFINED))
return JS_FALSE;
}
memmove(elems, elems + 1, (initlen - 1) * sizeof(jsval));
obj->setDenseArrayInitializedLength(initlen - 1);
} else {
@ -2306,6 +2319,9 @@ array_shift(JSContext *cx, uintN argc, Value *vp)
if (!GetElement(cx, obj, 0, &hole, vp))
return JS_FALSE;
if (hole && !cx->markTypeCallerUnexpected(TYPE_UNDEFINED))
return JS_FALSE;
/* Slide down the array above the first element. */
AutoValueRooter tvr(cx);
for (jsuint i = 0; i < length; i++) {
@ -3171,7 +3187,6 @@ array_TypeRemove(JSContext *cx, JSTypeFunction *jsfun, JSTypeCallsite *jssite)
if (!site->forceThisTypes(cx))
return;
site->thisTypes->addGetProperty(cx, site->script, site->pc, site->returnTypes, JSID_VOID);
site->returnTypes->addType(cx, TYPE_UNDEFINED);
}
static void
@ -3217,6 +3232,21 @@ array_TypeConcat(JSContext *cx, JSTypeFunction *jsfun, JSTypeCallsite *jssite)
}
}
static void
array_TypeSlice(JSContext *cx, JSTypeFunction *jsfun, JSTypeCallsite *jssite)
{
TypeCallsite *site = Valueify(jssite);
if (!site->forceThisTypes(cx))
return;
if (site->returnTypes) {
if (site->isNew)
site->returnTypes->addType(cx, TYPE_UNKNOWN);
site->thisTypes->addFilterPrimitives(cx, site->script, site->returnTypes, false);
}
}
/* Handler for all higher order array builtins. */
static void
array_TypeExtra(JSContext *cx, JSTypeFunction *jsfun, JSTypeCallsite *jssite,
@ -3324,7 +3354,7 @@ static JSFunctionSpec array_methods[] = {
/* Pythonic sequence methods. */
JS_FN_TYPE("concat", array_concat, 1,GENERIC, array_TypeConcat),
JS_FN_TYPE("slice", array_slice, 2,GENERIC, JS_TypeHandlerThis),
JS_FN_TYPE("slice", array_slice, 2,GENERIC, array_TypeSlice),
#if JS_HAS_ARRAY_EXTRAS
JS_FN_TYPE("indexOf", array_indexOf, 1,GENERIC, JS_TypeHandlerInt),