Assert prototype shapes when reading a hole from a dense array instead of calling a builtin (481328, r=brendan).

This commit is contained in:
Andreas Gal
2009-03-03 21:58:56 -08:00
parent fa2a1c5a3a
commit 870131b280
5 changed files with 26 additions and 20 deletions

View File

@@ -822,27 +822,25 @@ array_setProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
return JS_TRUE;
}
JSBool JS_FASTCALL
js_ObjectHasNumericPropertiesInAnyPrototype(JSContext *cx, JSObject *obj)
JSBool
js_PrototypeHasIndexedProperties(JSContext *cx, JSObject *obj)
{
JSObject *pobj = obj;
/* Walk up the prototype chain and see if this indexed element already exists. */
for (;;) {
pobj = JSVAL_TO_OBJECT(pobj->fslots[JSSLOT_PROTO]);
obj = JSVAL_TO_OBJECT(obj->fslots[JSSLOT_PROTO]);
/*
* If we hit the end of the prototype chain, its safe to set the element on the
* original object.
*/
if (!pobj)
if (!obj)
break;
/*
* If the prototype is a dense array, or a non-dense array that has numeric
* properties, return true.
*/
if (OBJ_IS_DENSE_ARRAY(cx, pobj) || (SCOPE_HAS_INDEXED_PROPERTIES(OBJ_SCOPE(pobj))))
if (OBJ_IS_DENSE_ARRAY(cx, obj) || (SCOPE_HAS_INDEXED_PROPERTIES(OBJ_SCOPE(obj))))
return JS_TRUE;
}
return JS_FALSE;
@@ -869,7 +867,7 @@ js_Array_dense_setelem(JSContext* cx, JSObject* obj, jsint i, jsval v)
return JS_FALSE;
if (obj->dslots[u] == JSVAL_HOLE) {
if (js_ObjectHasNumericPropertiesInAnyPrototype(cx, obj))
if (js_PrototypeHasIndexedProperties(cx, obj))
return JS_FALSE;
if (u >= jsuint(obj->fslots[JSSLOT_ARRAY_LENGTH]))
@@ -3505,5 +3503,3 @@ JS_DEFINE_CALLINFO_3(extern, OBJECT, js_NewUninitializedArray, CONTEXT, OBJECT,
JS_DEFINE_CALLINFO_3(extern, OBJECT, js_FastNewArrayWithLength, CONTEXT, OBJECT, UINT32, 0, 0)
JS_DEFINE_CALLINFO_3(extern, OBJECT, js_Array_1str, CONTEXT, OBJECT, STRING, 0, 0)
JS_DEFINE_CALLINFO_3(extern, BOOL, js_ArrayCompPush, CONTEXT, OBJECT, JSVAL, 0, 0)
JS_DEFINE_CALLINFO_2(extern, BOOL, js_ObjectHasNumericPropertiesInAnyPrototype,
CONTEXT, OBJECT, 0, 0)