blob: b71b38921e84d1a46b41dccbf89a0d1284adf26a [file] [log] [blame]
// |jit-test| error:done
load(libdir + "iteration.js");
function *f1() {
yield 1;
yield 2;
}
// Return after initial yield.
var it = f1();
assertIteratorResult(it.return(3), 3, true);
assertIteratorResult(it.return(Math), Math, true);
assertIteratorResult(it.return(), undefined, true);
assertIteratorDone(it);
// Return after other yield.
it = f1();
assertIteratorNext(it, 1);
assertIteratorResult(it.return(null), null, true);
assertIteratorDone(it);
// Finally blocks should run and can override the return value.
function *f2() {
try {
yield 1;
yield 2;
} finally {
return 9;
}
}
it = f2();
assertIteratorNext(it, 1);
assertIteratorResult(it.return(3), 9, true);
assertIteratorDone(it);
// Yield in finally block can override the return, but we should still
// return the correct value after that.
function *f3() {
try {
try {
yield 1;
yield 2;
} finally {
yield 3;
}
} finally {
yield 4;
}
}
it = f3();
assertIteratorNext(it, 1);
assertIteratorResult(it.return(9), 3, false);
assertIteratorNext(it, 4);
assertIteratorDone(it, 9);
assertIteratorDone(it, undefined);
// Finally block can throw.
function *f4() {
try {
yield 1;
yield 2;
} finally {
throw 3;
}
}
it = f4();
assertIteratorNext(it, 1);
assertThrowsValue(() => it.return(8), 3);
assertIteratorDone(it);
function *f5() {}
it = f5();
assertIteratorDone(it);
assertIteratorResult(it.return(3), 3, true);
assertIteratorDone(it);
function *f6() {
try {
yield 1;
yield 2;
} finally {
try {
return 9;
} finally {
yield 3;
}
}
}
it = f6();
assertIteratorNext(it, 1);
assertIteratorResult(it.return(5), 3, false);
assertIteratorDone(it, 9);
assertIteratorDone(it);
// If we yield in a finally block, a second .return() can override
// the first one.
function *f7() {
try {
yield 1;
yield 2;
} finally {
try {
yield 3;
} finally {
yield 4;
}
}
}
it = f7();
assertIteratorNext(it, 1);
assertIteratorResult(it.return(5), 3, false);
assertIteratorResult(it.return(6), 4, false);
assertIteratorDone(it, 6);
assertIteratorDone(it);
// If we yield in a finally block, .throw() should work.
function *f8() {
try {
yield 1;
yield 2;
} finally {
yield 3;
}
}
it = f8();
assertIteratorNext(it, 1);
assertIteratorResult(it.return(5), 3, false);
assertThrowsValue(() => it.throw(4), 4);
assertIteratorDone(it);
// If the generator is already running, we should throw a TypeError.
function *f9() {
try {
yield 1;
yield 2;
} finally {
it.return(4);
yield 3;
}
}
it = f9();
assertIteratorNext(it, 1);
assertThrowsInstanceOf(() => it.return(5), TypeError);
assertIteratorDone(it);
assertIteratorDone(it);
// Second return overrides first one and closes the generator.
function *f10() {
try {
yield 1;
} finally {
yield 2;
}
}
it = f10();
assertIteratorNext(it, 1);
assertIteratorResult(it.return(-1), 2, false);
assertIteratorResult(it.return(-2), -2, true);
assertIteratorDone(it);
function *f11() {
try {
try {
yield 1;
} finally {
throw 2;
}
} catch(e) {
yield e;
} finally {
yield 3;
}
}
it = f11();
assertIteratorNext(it, 1);
assertIteratorResult(it.return(9), 2, false);
assertIteratorNext(it, 3);
assertIteratorDone(it);
throw "done";