diff options
Diffstat (limited to 'js/src/jit-test/tests/generators/return.js')
-rw-r--r-- | js/src/jit-test/tests/generators/return.js | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/generators/return.js b/js/src/jit-test/tests/generators/return.js new file mode 100644 index 000000000..b71b38921 --- /dev/null +++ b/js/src/jit-test/tests/generators/return.js @@ -0,0 +1,181 @@ +// |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"; |