|
1 // Errors accessing next, done, or value don't cause an exception to be |
|
2 // thrown into the iterator of a yield*. |
|
3 |
|
4 function* g(n) { for (var i=0; i<n; i++) yield i; } |
|
5 function* delegate(iter) { return yield* iter; } |
|
6 |
|
7 var log = "", inner, outer; |
|
8 |
|
9 // That var is poisoooooon, p-poison poison... |
|
10 var Poison = new Error; |
|
11 |
|
12 function log_calls(method) { |
|
13 return function () { |
|
14 log += "x" |
|
15 return method.call(this); |
|
16 } |
|
17 } |
|
18 |
|
19 function poison(receiver, prop) { |
|
20 Object.defineProperty(receiver, prop, { get: function () { throw Poison } }); |
|
21 } |
|
22 |
|
23 // Poison inner.next. |
|
24 inner = g(10); |
|
25 outer = delegate(inner); |
|
26 inner.throw = log_calls(inner.throw); |
|
27 poison(inner, 'next') |
|
28 assertThrowsValue(outer.next.bind(outer), Poison); |
|
29 assertEq(log, ""); |
|
30 |
|
31 // Poison result value from inner. |
|
32 inner = g(10); |
|
33 outer = delegate(inner); |
|
34 inner.next = function () { return { done: true, get value() { throw Poison} } }; |
|
35 inner.throw = log_calls(inner.throw); |
|
36 assertThrowsValue(outer.next.bind(outer), Poison); |
|
37 assertEq(log, ""); |
|
38 |
|
39 // Poison result done from inner. |
|
40 inner = g(10); |
|
41 outer = delegate(inner); |
|
42 inner.next = function () { return { get done() { throw Poison }, value: 42 } }; |
|
43 inner.throw = log_calls(inner.throw); |
|
44 assertThrowsValue(outer.next.bind(outer), Poison); |
|
45 assertEq(log, ""); |
|
46 |
|
47 // mischief managed. |
|
48 if (typeof reportCompare == "function") |
|
49 reportCompare(true, true); |