зеркало из https://github.com/mozilla/pjs.git
Don't re-use cached iterators that have suppressed deleted properties (bug 633409, r=gal).
This commit is contained in:
Родитель
6a8a09e0cc
Коммит
40116825f5
|
@ -0,0 +1,13 @@
|
|||
// vim: set ts=4 sw=4 tw=99 et:
|
||||
x = { a: 1, b: 2, c: 3, d: 4, e: 5, f: 6 };
|
||||
|
||||
for (i in x)
|
||||
delete x.d;
|
||||
|
||||
x = { a: 1, b: 2, c: 3, d: 4, e: 5, f: 6 };
|
||||
y = [];
|
||||
for (i in x)
|
||||
y.push(i)
|
||||
|
||||
assertEq(y[3], "d");
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
// vim: set ts=4 sw=4 tw=99 et:
|
||||
|
||||
var o1 = {p1: 1};
|
||||
var o2 = {p1: 1, p2: 2};
|
||||
|
||||
for(var x in o1) {
|
||||
for(var y in o2) {
|
||||
delete o2.p2;
|
||||
}
|
||||
}
|
||||
|
||||
/* Don't fail cx->enumerators == obj assert, see bug comment #31 */
|
||||
|
|
@ -590,7 +590,7 @@ GetIterator(JSContext *cx, JSObject *obj, uintN flags, Value *vp)
|
|||
JSObject *proto = obj->getProto();
|
||||
if (last) {
|
||||
NativeIterator *lastni = last->getNativeIterator();
|
||||
if (!(lastni->flags & JSITER_ACTIVE) &&
|
||||
if (!(lastni->flags & (JSITER_ACTIVE|JSITER_UNREUSABLE)) &&
|
||||
obj->isNative() &&
|
||||
obj->shape() == lastni->shapes_array[0] &&
|
||||
proto && proto->isNative() &&
|
||||
|
@ -627,7 +627,7 @@ GetIterator(JSContext *cx, JSObject *obj, uintN flags, Value *vp)
|
|||
JSObject *iterobj = cx->compartment->nativeIterCache.get(key);
|
||||
if (iterobj) {
|
||||
NativeIterator *ni = iterobj->getNativeIterator();
|
||||
if (!(ni->flags & JSITER_ACTIVE) &&
|
||||
if (!(ni->flags & (JSITER_ACTIVE|JSITER_UNREUSABLE)) &&
|
||||
ni->shapes_key == key &&
|
||||
ni->shapes_length == shapes.length() &&
|
||||
Compare(ni->shapes_array, shapes.begin(), ni->shapes_length)) {
|
||||
|
@ -882,6 +882,10 @@ SuppressDeletedPropertyHelper(JSContext *cx, JSObject *obj, IdPredicate predicat
|
|||
memmove(idp, idp + 1, (props_end - (idp + 1)) * sizeof(jsid));
|
||||
ni->props_end = ni->end() - 1;
|
||||
}
|
||||
|
||||
/* Don't reuse modified native iterators. */
|
||||
ni->flags |= JSITER_UNREUSABLE;
|
||||
|
||||
if (predicate.matchesAtMostOne())
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -63,7 +63,8 @@
|
|||
* For cacheable native iterators, whether the iterator is currently active.
|
||||
* Not serialized by XDR.
|
||||
*/
|
||||
#define JSITER_ACTIVE 0x1000
|
||||
#define JSITER_ACTIVE 0x1000
|
||||
#define JSITER_UNREUSABLE 0x2000
|
||||
|
||||
namespace js {
|
||||
|
||||
|
|
|
@ -4032,7 +4032,8 @@ mjit::Compiler::iter(uintN flags)
|
|||
/* Test for active iterator. */
|
||||
Address flagsAddr(nireg, offsetof(NativeIterator, flags));
|
||||
masm.load32(flagsAddr, T1);
|
||||
Jump activeIterator = masm.branchTest32(Assembler::NonZero, T1, Imm32(JSITER_ACTIVE));
|
||||
Jump activeIterator = masm.branchTest32(Assembler::NonZero, T1,
|
||||
Imm32(JSITER_ACTIVE|JSITER_UNREUSABLE));
|
||||
stubcc.linkExit(activeIterator, Uses(1));
|
||||
|
||||
/* Compare shape of object with iterator. */
|
||||
|
@ -4224,9 +4225,8 @@ mjit::Compiler::iterEnd()
|
|||
Address flagAddr(T1, offsetof(NativeIterator, flags));
|
||||
masm.loadPtr(flagAddr, T2);
|
||||
|
||||
/* Test for (flags == ENUMERATE | ACTIVE). */
|
||||
Jump notEnumerate = masm.branch32(Assembler::NotEqual, T2,
|
||||
Imm32(JSITER_ENUMERATE | JSITER_ACTIVE));
|
||||
/* Test for a normal enumerate iterator. */
|
||||
Jump notEnumerate = masm.branchTest32(Assembler::Zero, T2, Imm32(JSITER_ENUMERATE));
|
||||
stubcc.linkExit(notEnumerate, Uses(1));
|
||||
|
||||
/* Clear active bit. */
|
||||
|
|
Загрузка…
Ссылка в новой задаче