blob: fb6b14aa3443ec6aecf3b25850b167d22f73104c [file] [log] [blame]
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001// Copyright 2014 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Ben Murdoch61f157c2016-09-16 13:49:30 +01005// Flags: --ignition-generators
6
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007// Test generator states.
8
9function Foo() {}
10function Bar() {}
11
12function assertIteratorResult(value, done, result) {
13 assertEquals({ value: value, done: done}, result);
14}
15
16function assertIteratorIsClosed(iter) {
17 assertIteratorResult(undefined, true, iter.next());
18 // Next and throw on a closed iterator.
19 assertDoesNotThrow(function() { iter.next(); });
20 assertThrows(function() { iter.throw(new Bar); }, Bar);
21}
22
23var iter;
24function* nextGenerator() { yield iter.next(); }
25function* throwGenerator() { yield iter.throw(new Bar); }
26
27// Throw on a suspendedStart iterator.
28iter = nextGenerator();
29assertThrows(function() { iter.throw(new Foo) }, Foo)
Ben Murdoch097c5b22016-05-18 11:27:45 +010030assertIteratorIsClosed(iter);
Emily Bernierd0a1eb72015-03-24 16:35:39 -040031assertThrows(function() { iter.throw(new Foo) }, Foo)
32assertIteratorIsClosed(iter);
33
34// The same.
35iter = throwGenerator();
36assertThrows(function() { iter.throw(new Foo) }, Foo)
37assertThrows(function() { iter.throw(new Foo) }, Foo)
38assertIteratorIsClosed(iter);
39
40// Next on an executing iterator raises a TypeError.
41iter = nextGenerator();
42assertThrows(function() { iter.next() }, TypeError)
43assertIteratorIsClosed(iter);
44
45// Throw on an executing iterator raises a TypeError.
46iter = throwGenerator();
47assertThrows(function() { iter.next() }, TypeError)
48assertIteratorIsClosed(iter);
49
50// Next on an executing iterator doesn't change the state of the
51// generator.
52iter = (function* () {
53 try {
54 iter.next();
55 yield 1;
56 } catch (e) {
57 try {
58 // This next() should raise the same exception, because the first
59 // next() left the iter in the executing state.
60 iter.next();
61 yield 2;
62 } catch (e) {
63 yield 3;
64 }
65 }
66 yield 4;
67})();
68assertIteratorResult(3, false, iter.next());
69assertIteratorResult(4, false, iter.next());
70assertIteratorIsClosed(iter);
Ben Murdoch097c5b22016-05-18 11:27:45 +010071
72
73// A return that doesn't close.
74{
75 let g = function*() { try {return 42} finally {yield 43} };
76
77 let x = g();
78 assertEquals({value: 43, done: false}, x.next());
79 assertEquals({value: 42, done: true}, x.next());
80}
81{
82 let x;
83 let g = function*() { try {return 42} finally {x.throw(666)} };
84
85 x = g();
86 assertThrows(() => x.next(), TypeError); // Still executing.
87}
88{
89 let x;
90 let g = function*() {
91 try {return 42} finally {try {x.throw(666)} catch(e) {}}
92 };
93
94 x = g();
95 assertEquals({value: 42, done: true}, x.next());
96}