Fix prototype guards on array hole ICs (bug 615440, r=dmandelin).

This commit is contained in:
David Anderson 2010-11-30 17:14:01 -08:00
Родитель 73e6445027
Коммит 884504296d
2 изменённых файлов: 21 добавлений и 20 удалений

Просмотреть файл

@ -0,0 +1,5 @@
Array.prototype.__proto__ = null;
for (var r = 0; r < 3; ++r) [][0] = 1;
// Don't crash.

Просмотреть файл

@ -2373,24 +2373,21 @@ SetElementIC::attachHoleStub(JSContext *cx, JSObject *obj, int32 keyval)
Assembler masm;
// Test for indexed properties in Array.prototype. It is safe to bake in
// this pointer because changing __proto__ will slowify.
JSObject *arrayProto = obj->getProto();
masm.move(ImmPtr(arrayProto), objReg);
Jump extendedArray = masm.branchTest32(Assembler::NonZero,
Address(objReg, offsetof(JSObject, flags)),
Imm32(JSObject::INDEXED));
Vector<Jump, 4> fails(cx);
// Text for indexed properties in Object.prototype. Guard that
// Array.prototype doesn't change, too.
JSObject *objProto = arrayProto->getProto();
Jump sameProto = masm.branchPtr(Assembler::NotEqual,
Address(objReg, offsetof(JSObject, proto)),
ImmPtr(objProto));
masm.move(ImmPtr(objProto), objReg);
Jump extendedObject = masm.branchTest32(Assembler::NonZero,
Address(objReg, offsetof(JSObject, flags)),
Imm32(JSObject::INDEXED));
// Test for indexed properties in Array.prototype. We test each shape
// along the proto chain. This affords us two optimizations:
// 1) Loading the prototype can be avoided because the shape would change;
// instead we can bake in their identities.
// 2) We only have to test the shape, rather than INDEXED.
for (JSObject *pobj = obj->getProto(); pobj; pobj = pobj->getProto()) {
if (!pobj->isNative())
return disable(cx, "non-native array prototype");
masm.move(ImmPtr(pobj), objReg);
Jump j = masm.guardShape(objReg, pobj);
if (!fails.append(j))
return error(cx);
}
// Restore |obj|.
masm.rematPayload(StateRemat::FromInt32(objRemat), objReg);
@ -2438,9 +2435,8 @@ SetElementIC::attachHoleStub(JSContext *cx, JSObject *obj, int32 keyval)
return disable(cx, "code memory is out of range");
// Patch all guards.
buffer.link(extendedArray, slowPathStart);
buffer.link(sameProto, slowPathStart);
buffer.link(extendedObject, slowPathStart);
for (size_t i = 0; i < fails.length(); i++)
buffer.link(fails[i], slowPathStart);
buffer.link(done, fastPathRejoin);
CodeLocationLabel cs = buffer.finalize();