Bug 1331585 - Allow falsy "done" values for IteratorClose due to exception during array destructuring

Issue #74
This commit is contained in:
janekptacijarabaci 2018-03-25 14:48:34 +02:00 • committed by Roy Tam
commit 4ac4296fce
3 changed files with 25 additions and 8 deletions

View file

@ -353,11 +353,11 @@ CloseLiveIteratorIon(JSContext* cx, const InlineFrameIterator& frame, JSTryNote*
RootedObject iterObject(cx, &v.toObject());
if (isDestructuring) {
Value v = si.read();
MOZ_ASSERT(v.isBoolean());
RootedValue doneValue(cx, si.read());
bool done = ToBoolean(doneValue);
// Do not call IteratorClose if the destructuring iterator is already
// done.
if (v.isTrue())
if (done)
return;
}
@ -654,9 +654,9 @@ ProcessTryNotesBaseline(JSContext* cx, const JitFrameIterator& frame, Environmen
uint8_t* framePointer;
uint8_t* stackPointer;
BaselineFrameAndStackPointersFromTryNote(tn, frame, &framePointer, &stackPointer);
Value doneValue(*(reinterpret_cast<Value*>(stackPointer)));
MOZ_ASSERT(doneValue.isBoolean());
if (doneValue.isFalse()) {
RootedValue doneValue(cx, *(reinterpret_cast<Value*>(stackPointer)));
bool done = ToBoolean(doneValue);
if (!done) {
Value iterValue(*(reinterpret_cast<Value*>(stackPointer) + 1));
RootedObject iterObject(cx, &iterValue.toObject());
if (!IteratorCloseForException(cx, iterObject)) {

View file

@ -43,6 +43,22 @@ function test() {
}, "in lhs");
assertEq(returnCalled, ++returnCalledExpected);
// throw in lhs ref calls IteratorClose with falsy "done".
iterable[Symbol.iterator] = makeIterator({
next: function() {
// "done" is undefined.
return {};
},
ret: function() {
returnCalled++;
return {};
}
});
assertThrowsValue(function() {
0, [...{}[throwlhs()]] = iterable;
}, "in lhs");
assertEq(returnCalled, ++returnCalledExpected);
// throw in iter.next doesn't call IteratorClose
iterable[Symbol.iterator] = makeIterator({
next: function() {

View file

@ -1205,8 +1205,9 @@ ProcessTryNotes(JSContext* cx, EnvironmentIter& ei, InterpreterRegs& regs)
// stack. The iterator object is second from the top.
MOZ_ASSERT(tn->stackDepth > 1);
Value* sp = regs.spForStackDepth(tn->stackDepth);
MOZ_ASSERT(sp[-1].isBoolean());
if (sp[-1].isFalse()) {
RootedValue doneValue(cx, sp[-1]);
bool done = ToBoolean(doneValue);
if (!done) {
RootedObject iterObject(cx, &sp[-2].toObject());
if (!IteratorCloseForException(cx, iterObject)) {
SettleOnTryNote(cx, tn, ei, regs);