OLD | NEW |
| (Empty) |
1 // Copyright 2016 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 | |
5 // Flags: --ignition --harmony-do-expressions | |
6 // Flags: --allow-natives-syntax --turbo --turbo-from-bytecode | |
7 | |
8 | |
9 // This file is identical to mjsunit/harmony/generators.js, except for its Flags | |
10 // lines. The purpose is to explicitly mention --turbo-from-bytecode such that | |
11 // Clusterfuzz can thoroughly test the new generators implementation. | |
12 | |
13 | |
14 function MaybeOptimizeOrDeoptimize(f) { | |
15 let x = Math.random(); // --random-seed makes this deterministic | |
16 if (x <= 0.33) { | |
17 %OptimizeFunctionOnNextCall(f); | |
18 } else if (x <= 0.66) { | |
19 %DeoptimizeFunction(f); | |
20 } | |
21 } | |
22 | |
23 function Next(generator, ...args) { | |
24 MaybeOptimizeOrDeoptimize(%GeneratorGetFunction(generator)); | |
25 return generator.next(...args); | |
26 } | |
27 | |
28 function Return(generator, ...args) { | |
29 MaybeOptimizeOrDeoptimize(%GeneratorGetFunction(generator)); | |
30 return generator.return(...args); | |
31 } | |
32 | |
33 function Throw(generator, ...args) { | |
34 MaybeOptimizeOrDeoptimize(%GeneratorGetFunction(generator)); | |
35 return generator.throw(...args); | |
36 } | |
37 | |
38 | |
39 { // yield in try-catch | |
40 | |
41 let g = function*() { | |
42 try {yield 1} catch (error) {assertEquals("caught", error)} | |
43 }; | |
44 | |
45 assertThrowsEquals(() => Throw(g(), "not caught"), "not caught"); | |
46 | |
47 { | |
48 let x = g(); | |
49 assertEquals({value: 1, done: false}, Next(x)); | |
50 assertEquals({value: undefined, done: true}, Throw(x, "caught")); | |
51 } | |
52 | |
53 { | |
54 let x = g(); | |
55 assertEquals({value: 1, done: false}, Next(x)); | |
56 assertEquals({value: undefined, done: true}, Next(x)); | |
57 assertThrowsEquals(() => Throw(x, "not caught"), "not caught"); | |
58 } | |
59 } | |
60 | |
61 | |
62 { // return that doesn't close | |
63 let g = function*() { try {return 42} finally {yield 43} }; | |
64 | |
65 { | |
66 let x = g(); | |
67 assertEquals({value: 43, done: false}, Next(x)); | |
68 assertEquals({value: 42, done: true}, Next(x)); | |
69 } | |
70 } | |
71 | |
72 | |
73 { // return that doesn't close | |
74 let x; | |
75 let g = function*() { try {return 42} finally {Throw(x, 666)} }; | |
76 | |
77 { | |
78 x = g(); | |
79 assertThrows(() => Next(x), TypeError); // still executing | |
80 } | |
81 } | |
82 | |
83 | |
84 { // yield in try-finally, finally clause performs return | |
85 | |
86 let g = function*() { try {yield 42} finally {return 13} }; | |
87 | |
88 { // "return" closes at suspendedStart | |
89 let x = g(); | |
90 assertEquals({value: 666, done: true}, Return(x, 666)); | |
91 assertEquals({value: undefined, done: true}, Next(x, 42)); | |
92 assertThrowsEquals(() => Throw(x, 43), 43); | |
93 assertEquals({value: 42, done: true}, Return(x, 42)); | |
94 } | |
95 | |
96 { // "throw" closes at suspendedStart | |
97 let x = g(); | |
98 assertThrowsEquals(() => Throw(x, 666), 666); | |
99 assertEquals({value: undefined, done: true}, Next(x, 42)); | |
100 assertEquals({value: 43, done: true}, Return(x, 43)); | |
101 assertThrowsEquals(() => Throw(x, 44), 44); | |
102 } | |
103 | |
104 { // "next" closes at suspendedYield | |
105 let x = g(); | |
106 assertEquals({value: 42, done: false}, Next(x)); | |
107 assertEquals({value: 13, done: true}, Next(x, 666)); | |
108 assertEquals({value: undefined, done: true}, Next(x, 666)); | |
109 assertThrowsEquals(() => Throw(x, 666), 666); | |
110 } | |
111 | |
112 { // "return" closes at suspendedYield | |
113 let x = g(); | |
114 assertEquals({value: 42, done: false}, Next(x)); | |
115 assertEquals({value: 13, done: true}, Return(x, 666)); | |
116 assertEquals({value: undefined, done: true}, Next(x, 666)); | |
117 assertEquals({value: 666, done: true}, Return(x, 666)); | |
118 } | |
119 | |
120 { // "throw" closes at suspendedYield | |
121 let x = g(); | |
122 assertEquals({value: 42, done: false}, Next(x)); | |
123 assertEquals({value: 13, done: true}, Throw(x, 666)); | |
124 assertThrowsEquals(() => Throw(x, 666), 666); | |
125 assertEquals({value: undefined, done: true}, Next(x, 666)); | |
126 } | |
127 } | |
128 | |
129 | |
130 { // yield in try-finally, finally clause doesn't perform return | |
131 | |
132 let g = function*() { try {yield 42} finally {13} }; | |
133 | |
134 { // "return" closes at suspendedStart | |
135 let x = g(); | |
136 assertEquals({value: 666, done: true}, Return(x, 666)); | |
137 assertEquals({value: undefined, done: true}, Next(x, 42)); | |
138 assertThrowsEquals(() => Throw(x, 43), 43); | |
139 assertEquals({value: 42, done: true}, Return(x, 42)); | |
140 } | |
141 | |
142 { // "throw" closes at suspendedStart | |
143 let x = g(); | |
144 assertThrowsEquals(() => Throw(x, 666), 666); | |
145 assertEquals({value: undefined, done: true}, Next(x, 42)); | |
146 assertEquals({value: 43, done: true}, Return(x, 43)); | |
147 assertThrowsEquals(() => Throw(x, 44), 44); | |
148 } | |
149 | |
150 { // "next" closes at suspendedYield | |
151 let x = g(); | |
152 assertEquals({value: 42, done: false}, Next(x)); | |
153 assertEquals({value: undefined, done: true}, Next(x, 666)); | |
154 assertEquals({value: undefined, done: true}, Next(x, 666)); | |
155 assertThrowsEquals(() => Throw(x, 666), 666); | |
156 assertEquals({value: 42, done: true}, Return(x, 42)); | |
157 } | |
158 | |
159 { // "return" closes at suspendedYield | |
160 let x = g(); | |
161 assertEquals({value: 42, done: false}, Next(x)); | |
162 assertEquals({value: 666, done: true}, Return(x, 666)); | |
163 assertEquals({value: undefined, done: true}, Next(x, 666)); | |
164 assertThrowsEquals(() => Throw(x, 44), 44); | |
165 assertEquals({value: 42, done: true}, Return(x, 42)); | |
166 } | |
167 | |
168 { // "throw" closes at suspendedYield | |
169 let x = g(); | |
170 assertEquals({value: 42, done: false}, Next(x)); | |
171 assertThrowsEquals(() => Throw(x, 666), 666); | |
172 assertEquals({value: undefined, done: true}, Next(x, 666)); | |
173 assertThrowsEquals(() => Throw(x, 666), 666); | |
174 assertEquals({value: 42, done: true}, Return(x, 42)); | |
175 } | |
176 } | |
177 | |
178 | |
179 { // yield in try-finally, finally clause yields and performs return | |
180 | |
181 let g = function*() { try {yield 42} finally {yield 43; return 13} }; | |
182 | |
183 { | |
184 let x = g(); | |
185 assertEquals({value: 42, done: false}, Next(x)); | |
186 assertEquals({value: 43, done: false}, Return(x, 666)); | |
187 assertEquals({value: 13, done: true}, Next(x)); | |
188 assertEquals({value: 666, done: true}, Return(x, 666)); | |
189 } | |
190 | |
191 { | |
192 let x = g(); | |
193 assertEquals({value: 666, done: true}, Return(x, 666)); | |
194 assertEquals({value: undefined, done: true}, Next(x)); | |
195 assertEquals({value: 666, done: true}, Return(x, 666)); | |
196 } | |
197 } | |
198 | |
199 | |
200 { // yield in try-finally, finally clause yields and doesn't perform return | |
201 | |
202 let g = function*() { try {yield 42} finally {yield 43; 13} }; | |
203 | |
204 { | |
205 let x = g(); | |
206 assertEquals({value: 42, done: false}, Next(x)); | |
207 assertEquals({value: 43, done: false}, Return(x, 666)); | |
208 assertEquals({value: 666, done: true}, Next(x)); | |
209 assertEquals({value: 5, done: true}, Return(x, 5)); | |
210 } | |
211 | |
212 { | |
213 let x = g(); | |
214 assertEquals({value: 666, done: true}, Return(x, 666)); | |
215 assertEquals({value: undefined, done: true}, Next(x)); | |
216 assertEquals({value: 666, done: true}, Return(x, 666)); | |
217 } | |
218 } | |
219 | |
220 | |
221 { // yield*, finally clause performs return | |
222 | |
223 let h = function*() { try {yield 42} finally {yield 43; return 13} }; | |
224 let g = function*() { yield 1; yield yield* h(); }; | |
225 | |
226 { | |
227 let x = g(); | |
228 assertEquals({value: 1, done: false}, Next(x)); | |
229 assertEquals({value: 42, done: false}, Next(x)); | |
230 assertEquals({value: 43, done: false}, Next(x, 666)); | |
231 assertEquals({value: 13, done: false}, Next(x)); | |
232 assertEquals({value: undefined, done: true}, Next(x)); | |
233 } | |
234 | |
235 { | |
236 let x = g(); | |
237 assertEquals({value: 1, done: false}, Next(x)); | |
238 assertEquals({value: 42, done: false}, Next(x)); | |
239 assertEquals({value: 43, done: false}, Return(x, 666)); | |
240 assertEquals({value: 13, done: false}, Next(x)); | |
241 assertEquals({value: undefined, done: true}, Next(x)); | |
242 } | |
243 | |
244 { | |
245 let x = g(); | |
246 assertEquals({value: 1, done: false}, Next(x)); | |
247 assertEquals({value: 42, done: false}, Next(x)); | |
248 assertEquals({value: 43, done: false}, Throw(x, 666)); | |
249 assertEquals({value: 13, done: false}, Next(x)); | |
250 assertEquals({value: undefined, done: true}, Next(x)); | |
251 } | |
252 } | |
253 | |
254 | |
255 { // yield*, finally clause does not perform return | |
256 | |
257 let h = function*() { try {yield 42} finally {yield 43; 13} }; | |
258 let g = function*() { yield 1; yield yield* h(); }; | |
259 | |
260 { | |
261 let x = g(); | |
262 assertEquals({value: 1, done: false}, Next(x)); | |
263 assertEquals({value: 42, done: false}, Next(x)); | |
264 assertEquals({value: 43, done: false}, Next(x, 666)); | |
265 assertEquals({value: undefined, done: false}, Next(x)); | |
266 assertEquals({value: undefined, done: true}, Next(x)); | |
267 } | |
268 | |
269 { | |
270 let x = g(); | |
271 assertEquals({value: 1, done: false}, Next(x)); | |
272 assertEquals({value: 42, done: false}, Next(x)); | |
273 assertEquals({value: 43, done: false}, Return(x, 44)); | |
274 assertEquals({value: 44, done: false}, Next(x)); | |
275 assertEquals({value: undefined, done: true}, Next(x)); | |
276 } | |
277 | |
278 { | |
279 let x = g(); | |
280 assertEquals({value: 1, done: false}, Next(x)); | |
281 assertEquals({value: 42, done: false}, Next(x)); | |
282 assertEquals({value: 43, done: false}, Throw(x, 666)); | |
283 assertThrowsEquals(() => Next(x), 666); | |
284 } | |
285 } | |
286 | |
287 | |
288 { // yield*, .return argument is final result | |
289 | |
290 function* inner() { | |
291 yield 2; | |
292 } | |
293 | |
294 function* g() { | |
295 yield 1; | |
296 return yield* inner(); | |
297 } | |
298 | |
299 { | |
300 let x = g(); | |
301 assertEquals({value: 1, done: false}, Next(x)); | |
302 assertEquals({value: 2, done: false}, Next(x)); | |
303 assertEquals({value: 42, done: true}, Return(x, 42)); | |
304 } | |
305 } | |
306 | |
307 | |
308 // More or less random tests from here on. | |
309 | |
310 | |
311 { | |
312 function* foo() { } | |
313 let g = foo(); | |
314 assertEquals({value: undefined, done: true}, Next(g)); | |
315 assertEquals({value: undefined, done: true}, Next(g)); | |
316 } | |
317 | |
318 { | |
319 function* foo() { return new.target } | |
320 let g = foo(); | |
321 assertEquals({value: undefined, done: true}, Next(g)); | |
322 assertEquals({value: undefined, done: true}, Next(g)); | |
323 } | |
324 | |
325 { | |
326 function* foo() { throw 666; return 42} | |
327 let g = foo(); | |
328 assertThrowsEquals(() => Next(g), 666); | |
329 assertEquals({value: undefined, done: true}, Next(g)); | |
330 } | |
331 | |
332 { | |
333 function* foo(a) { return a; } | |
334 let g = foo(42); | |
335 assertEquals({value: 42, done: true}, Next(g)); | |
336 assertEquals({value: undefined, done: true}, Next(g)); | |
337 } | |
338 | |
339 { | |
340 function* foo(a) { a.iwashere = true; return a; } | |
341 let x = {}; | |
342 let g = foo(x); | |
343 assertEquals({value: {iwashere: true}, done: true}, Next(g)); | |
344 assertEquals({value: undefined, done: true}, Next(g)); | |
345 } | |
346 | |
347 { | |
348 let a = 42; | |
349 function* foo() { return a; } | |
350 let g = foo(); | |
351 assertEquals({value: 42, done: true}, Next(g)); | |
352 assertEquals({value: undefined, done: true}, Next(g)); | |
353 } | |
354 | |
355 { | |
356 let a = 40; | |
357 function* foo(b) { return a + b; } | |
358 let g = foo(2); | |
359 assertEquals({value: 42, done: true}, Next(g)); | |
360 assertEquals({value: undefined, done: true}, Next(g)); | |
361 } | |
362 | |
363 { | |
364 let a = 40; | |
365 function* foo(b) { a--; b++; return a + b; } | |
366 let g = foo(2); | |
367 assertEquals({value: 42, done: true}, Next(g)); | |
368 assertEquals({value: undefined, done: true}, Next(g)); | |
369 } | |
370 | |
371 { | |
372 let g; | |
373 function* foo() { Next(g) } | |
374 g = foo(); | |
375 assertThrows(() => Next(g), TypeError); | |
376 assertEquals({value: undefined, done: true}, Next(g)); | |
377 } | |
378 | |
379 { | |
380 function* foo() { yield 2; yield 3; yield 4 } | |
381 g = foo(); | |
382 assertEquals({value: 2, done: false}, Next(g)); | |
383 assertEquals({value: 3, done: false}, Next(g)); | |
384 assertEquals({value: 4, done: false}, Next(g)); | |
385 assertEquals({value: undefined, done: true}, Next(g)); | |
386 assertEquals({value: undefined, done: true}, Next(g)); | |
387 } | |
388 | |
389 | |
390 { | |
391 function* foo() { yield 2; if (true) { yield 3 }; yield 4 } | |
392 g = foo(); | |
393 assertEquals({value: 2, done: false}, Next(g)); | |
394 assertEquals({value: 3, done: false}, Next(g)); | |
395 assertEquals({value: 4, done: false}, Next(g)); | |
396 assertEquals({value: undefined, done: true}, Next(g)); | |
397 assertEquals({value: undefined, done: true}, Next(g)); | |
398 } | |
399 | |
400 { | |
401 function* foo() { yield 2; if (true) { yield 3; yield 4 } } | |
402 g = foo(); | |
403 assertEquals({value: 2, done: false}, Next(g)); | |
404 assertEquals({value: 3, done: false}, Next(g)); | |
405 assertEquals({value: 4, done: false}, Next(g)); | |
406 assertEquals({value: undefined, done: true}, Next(g)); | |
407 assertEquals({value: undefined, done: true}, Next(g)); | |
408 } | |
409 | |
410 { | |
411 function* foo() { yield 2; if (false) { yield 3 }; yield 4 } | |
412 g = foo(); | |
413 assertEquals({value: 2, done: false}, Next(g)); | |
414 assertEquals({value: 4, done: false}, Next(g)); | |
415 assertEquals({value: undefined, done: true}, Next(g)); | |
416 assertEquals({value: undefined, done: true}, Next(g)); | |
417 } | |
418 | |
419 { | |
420 function* foo() { yield 2; while (true) { yield 3 }; yield 4 } | |
421 g = foo(); | |
422 assertEquals({value: 2, done: false}, Next(g)); | |
423 assertEquals({value: 3, done: false}, Next(g)); | |
424 assertEquals({value: 3, done: false}, Next(g)); | |
425 assertEquals({value: 3, done: false}, Next(g)); | |
426 assertEquals({value: 3, done: false}, Next(g)); | |
427 } | |
428 | |
429 { | |
430 function* foo() { yield 2; (yield 3) + 42; yield 4 } | |
431 g = foo(); | |
432 assertEquals({value: 2, done: false}, Next(g)); | |
433 assertEquals({value: 3, done: false}, Next(g)); | |
434 assertEquals({value: 4, done: false}, Next(g)); | |
435 } | |
436 | |
437 { | |
438 function* foo() { yield 2; (do {yield 3}) + 42; yield 4 } | |
439 g = foo(); | |
440 assertEquals({value: 2, done: false}, Next(g)); | |
441 assertEquals({value: 3, done: false}, Next(g)); | |
442 assertEquals({value: 4, done: false}, Next(g)); | |
443 } | |
444 | |
445 { | |
446 function* foo() { yield 2; return (yield 3) + 42; yield 4 } | |
447 g = foo(); | |
448 assertEquals({value: 2, done: false}, Next(g)); | |
449 assertEquals({value: 3, done: false}, Next(g)); | |
450 assertEquals({value: 42, done: true}, Next(g, 0)); | |
451 assertEquals({value: undefined, done: true}, Next(g)); | |
452 } | |
453 | |
454 { | |
455 let x = 42; | |
456 function* foo() { | |
457 yield x; | |
458 for (let x in {a: 1, b: 2}) { | |
459 let i = 2; | |
460 yield x; | |
461 yield i; | |
462 do { | |
463 yield i; | |
464 } while (i-- > 0); | |
465 } | |
466 yield x; | |
467 return 5; | |
468 } | |
469 g = foo(); | |
470 assertEquals({value: 42, done: false}, Next(g)); | |
471 assertEquals({value: 'a', done: false}, Next(g)); | |
472 assertEquals({value: 2, done: false}, Next(g)); | |
473 assertEquals({value: 2, done: false}, Next(g)); | |
474 assertEquals({value: 1, done: false}, Next(g)); | |
475 assertEquals({value: 0, done: false}, Next(g)); | |
476 assertEquals({value: 'b', done: false}, Next(g)); | |
477 assertEquals({value: 2, done: false}, Next(g)); | |
478 assertEquals({value: 2, done: false}, Next(g)); | |
479 assertEquals({value: 1, done: false}, Next(g)); | |
480 assertEquals({value: 0, done: false}, Next(g)); | |
481 assertEquals({value: 42, done: false}, Next(g)); | |
482 assertEquals({value: 5, done: true}, Next(g)); | |
483 } | |
484 | |
485 { | |
486 let a = 3; | |
487 function* foo() { | |
488 let b = 4; | |
489 yield 1; | |
490 { let c = 5; yield 2; yield a; yield b; yield c; } | |
491 } | |
492 g = foo(); | |
493 assertEquals({value: 1, done: false}, Next(g)); | |
494 assertEquals({value: 2, done: false}, Next(g)); | |
495 assertEquals({value: 3, done: false}, Next(g)); | |
496 assertEquals({value: 4, done: false}, Next(g)); | |
497 assertEquals({value: 5, done: false}, Next(g)); | |
498 assertEquals({value: undefined, done: true}, Next(g)); | |
499 } | |
500 | |
501 { | |
502 function* foo() { | |
503 yield 42; | |
504 yield 42; | |
505 yield 42; | |
506 yield 42; | |
507 yield 42; | |
508 yield 42; | |
509 yield 42; | |
510 yield 42; | |
511 yield 42; | |
512 yield 42; | |
513 yield 42; | |
514 yield 42; | |
515 yield 42; | |
516 yield 42; | |
517 yield 42; | |
518 yield 42; | |
519 yield 42; | |
520 yield 42; | |
521 yield 42; | |
522 yield 42; | |
523 yield 42; | |
524 yield 42; | |
525 yield 42; | |
526 yield 42; | |
527 yield 42; | |
528 yield 42; | |
529 yield 42; | |
530 yield 42; | |
531 yield 42; | |
532 yield 42; | |
533 yield 42; | |
534 yield 42; | |
535 yield 42; | |
536 yield 42; | |
537 yield 42; | |
538 yield 42; | |
539 yield 42; | |
540 yield 42; | |
541 yield 42; | |
542 yield 42; | |
543 yield 42; | |
544 yield 42; | |
545 yield 42; | |
546 yield 42; | |
547 yield 42; | |
548 yield 42; | |
549 yield 42; | |
550 yield 42; | |
551 yield 42; | |
552 yield 42; | |
553 yield 42; | |
554 yield 42; | |
555 yield 42; | |
556 yield 42; | |
557 yield 42; | |
558 yield 42; | |
559 yield 42; | |
560 yield 42; | |
561 yield 42; | |
562 yield 42; | |
563 yield 42; | |
564 yield 42; | |
565 yield 42; | |
566 yield 42; | |
567 yield 42; | |
568 yield 42; | |
569 yield 42; | |
570 yield 42; | |
571 yield 42; | |
572 yield 42; | |
573 yield 42; | |
574 yield 42; | |
575 yield 42; | |
576 yield 42; | |
577 yield 42; | |
578 yield 42; | |
579 yield 42; | |
580 yield 42; | |
581 yield 42; | |
582 yield 42; | |
583 yield 42; | |
584 yield 42; | |
585 yield 42; | |
586 yield 42; | |
587 yield 42; | |
588 yield 42; | |
589 yield 42; | |
590 yield 42; | |
591 yield 42; | |
592 yield 42; | |
593 yield 42; | |
594 yield 42; | |
595 yield 42; | |
596 yield 42; | |
597 yield 42; | |
598 yield 42; | |
599 yield 42; | |
600 yield 42; | |
601 yield 42; | |
602 yield 42; | |
603 } | |
604 g = foo(); | |
605 for (let i = 0; i < 100; ++i) { | |
606 assertEquals({value: 42, done: false}, i%25 === 0 ? Next(g) : g.next()); | |
607 } | |
608 assertEquals({value: undefined, done: true}, Next(g)); | |
609 } | |
610 | |
611 { | |
612 function* foo() { | |
613 for (let i = 0; i < 3; ++i) { | |
614 let j = 0 | |
615 yield i; | |
616 do { | |
617 yield (i + 10); | |
618 } while (++j < 2); | |
619 } | |
620 } | |
621 g = foo(); | |
622 assertEquals({value: 0, done: false}, Next(g)); | |
623 assertEquals({value: 10, done: false}, Next(g)); | |
624 assertEquals({value: 10, done: false}, Next(g)); | |
625 assertEquals({value: 1, done: false}, Next(g)); | |
626 assertEquals({value: 11, done: false}, Next(g)); | |
627 assertEquals({value: 11, done: false}, Next(g)); | |
628 assertEquals({value: 2, done: false}, Next(g)); | |
629 assertEquals({value: 12, done: false}, Next(g)); | |
630 assertEquals({value: 12, done: false}, Next(g)); | |
631 assertEquals({value: undefined, done: true}, Next(g)); | |
632 } | |
633 | |
634 { | |
635 let foo = function*() { | |
636 while (true) { | |
637 if (true || false) yield 42; | |
638 continue; | |
639 } | |
640 } | |
641 g = foo(); | |
642 assertEquals({value: 42, done: false}, Next(g)); | |
643 assertEquals({value: 42, done: false}, Next(g)); | |
644 assertEquals({value: 42, done: false}, Next(g)); | |
645 } | |
646 | |
647 { | |
648 let foo = function*() { | |
649 yield* (function*() { yield 42; }()); | |
650 assertUnreachable(); | |
651 } | |
652 g = foo(); | |
653 assertEquals({value: 42, done: false}, Next(g)); | |
654 assertEquals({value: 23, done: true}, Return(g, 23)); | |
655 } | |
656 | |
657 { | |
658 let iterable = { | |
659 [Symbol.iterator]() { | |
660 return { next() { return {} } }; | |
661 } | |
662 }; | |
663 let foo = function*() { yield* iterable }; | |
664 g = foo(); | |
665 g.next(); | |
666 assertThrows(() => Throw(g), TypeError); | |
667 } | |
OLD | NEW |