• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
6function* g() { yield 42; return 88 };
7
8
9// Return method is "undefined".
10{
11  g.prototype.return = null;
12
13
14  assertEquals(undefined, (() => {
15    for (var x of g()) { break; }
16  })());
17
18  assertEquals(undefined, (() => {
19    for (let x of g()) { break; }
20  })());
21
22  assertEquals(undefined, (() => {
23    for (const x of g()) { break; }
24  })());
25
26  assertEquals(undefined, (() => {
27    for (x of g()) { break; }
28  })());
29
30
31  assertThrowsEquals(() => {
32    for (var x of g()) { throw 42; }
33  }, 42);
34
35  assertThrowsEquals(() => {
36    for (let x of g()) { throw 42; }
37  }, 42);
38
39  assertThrowsEquals(() => {
40    for (const x of g()) { throw 42; }
41  }, 42);
42
43  assertThrowsEquals(() => {
44    for (x of g()) { throw 42; }
45  }, 42);
46
47
48  assertEquals(42, (() => {
49    for (var x of g()) { return 42; }
50  })());
51
52  assertEquals(42, (() => {
53    for (let x of g()) { return 42; }
54  })());
55
56  assertEquals(42, (() => {
57    for (const x of g()) { return 42; }
58  })());
59
60  assertEquals(42, (() => {
61    for (x of g()) { return 42; }
62  })());
63
64
65  assertEquals(42, eval('for (var x of g()) { x; }'));
66
67  assertEquals(42, eval('for (let x of g()) { x; }'));
68
69  assertEquals(42, eval('for (const x of g()) { x; }'));
70
71  assertEquals(42, eval('for (x of g()) { x; }'));
72
73
74  assertEquals(42, (() => {
75    var [x] = g(); return x;
76  })());
77
78  assertEquals(42, (() => {
79    let [x] = g(); return x;
80  })());
81
82  assertEquals(42, (() => {
83    const [x] = g(); return x;
84  })());
85
86  assertEquals(42, (() => {
87    [x] = g(); return x;
88  })());
89
90  assertEquals(42,
91    (([x]) => x)(g())
92  );
93}
94
95
96// Return method is not callable.
97{
98  g.prototype.return = 666;
99
100
101  assertThrows(() => {
102    for (var x of g()) { break; }
103  }, TypeError);
104
105  assertThrows(() => {
106    for (let x of g()) { break; }
107  }, TypeError);
108
109  assertThrows(() => {
110    for (const x of g()) { break; }
111  }, TypeError);
112
113  assertThrows(() => {
114    for (x of g()) { break; }
115  }, TypeError);
116
117
118  assertThrows(() => {
119    for (var x of g()) { throw 666; }
120  }, TypeError);
121
122  assertThrows(() => {
123    for (let x of g()) { throw 666; }
124  }, TypeError);
125
126  assertThrows(() => {
127    for (const x of g()) { throw 666; }
128  }, TypeError);
129
130  assertThrows(() => {
131    for (x of g()) { throw 666; }
132  }, TypeError);
133
134
135  assertThrows(() => {
136    for (var x of g()) { return 666; }
137  }, TypeError);
138
139  assertThrows(() => {
140    for (let x of g()) { return 666; }
141  }, TypeError);
142
143  assertThrows(() => {
144    for (const x of g()) { return 666; }
145  }, TypeError);
146
147  assertThrows(() => {
148    for (x of g()) { return 666; }
149  }, TypeError);
150
151
152  assertEquals(42, eval('for (var x of g()) { x; }'));
153
154  assertEquals(42, eval('for (let x of g()) { x; }'));
155
156  assertEquals(42, eval('for (const x of g()) { x; }'));
157
158  assertEquals(42, eval('for (x of g()) { x; }'));
159
160
161  assertThrows(() => {
162    var [x] = g(); return x;
163  }, TypeError);
164
165  assertThrows(() => {
166    let [x] = g(); return x;
167  }, TypeError);
168
169  assertThrows(() => {
170    const [x] = g(); return x;
171  }, TypeError);
172
173  assertThrows(() => {
174    [x] = g(); return x;
175  }, TypeError);
176
177  assertThrows(() => {
178    (([x]) => x)(g());
179  }, TypeError);
180}
181
182
183// Return method does not return an object.
184{
185  g.prototype.return = () => 666;
186
187
188  assertThrows(() => {
189    for (var x of g()) { break; }
190  }, TypeError);
191
192  assertThrows(() => {
193    for (let x of g()) { break; }
194  }, TypeError);
195
196  assertThrows(() => {
197    for (const x of g()) { break; }
198  }, TypeError);
199
200  assertThrows(() => {
201    for (x of g()) { break; }
202  }, TypeError);
203
204
205  // Throw from the body of a for loop 'wins' vs throw
206  // originating from a bad 'return' value.
207
208  assertThrowsEquals(() => {
209    for (var x of g()) { throw 666; }
210  }, 666);
211
212  assertThrowsEquals(() => {
213    for (let x of g()) { throw 666; }
214  }, 666);
215
216  assertThrowsEquals(() => {
217    for (const x of g()) { throw 666; }
218  }, 666);
219
220  assertThrowsEquals(() => {
221    for (x of g()) { throw 666; }
222  }, 666);
223
224
225  assertThrows(() => {
226    for (var x of g()) { return 666; }
227  }, TypeError);
228
229  assertThrows(() => {
230    for (let x of g()) { return 666; }
231  }, TypeError);
232
233  assertThrows(() => {
234    for (const x of g()) { return 666; }
235  }, TypeError);
236
237  assertThrows(() => {
238    for (x of g()) { return 666; }
239  }, TypeError);
240
241
242  assertEquals(42, eval('for (var x of g()) { x; }'));
243
244  assertEquals(42, eval('for (let x of g()) { x; }'));
245
246  assertEquals(42, eval('for (const x of g()) { x; }'));
247
248  assertEquals(42, eval('for (x of g()) { x; }'));
249
250
251  assertThrows(() => {
252    var [x] = g(); return x;
253  }, TypeError);
254
255  assertThrows(() => {
256    let [x] = g(); return x;
257  }, TypeError);
258
259  assertThrows(() => {
260    const [x] = g(); return x;
261  }, TypeError);
262
263  assertThrows(() => {
264    [x] = g(); return x;
265  }, TypeError);
266
267  assertThrows(() => {
268    (([x]) => x)(g());
269  }, TypeError);
270}
271
272
273// Return method returns an object.
274{
275  let log = [];
276  g.prototype.return = (...args) => { log.push(args); return {} };
277
278
279  log = [];
280  for (var x of g()) { break; }
281  assertEquals([[]], log);
282
283  log = [];
284  for (let x of g()) { break; }
285  assertEquals([[]], log);
286
287  log = [];
288  for (const x of g()) { break; }
289  assertEquals([[]], log);
290
291  log = [];
292  for (x of g()) { break; }
293  assertEquals([[]], log);
294
295
296  log = [];
297  assertThrowsEquals(() => {
298    for (var x of g()) { throw 42; }
299  }, 42);
300  assertEquals([[]], log);
301
302  log = [];
303  assertThrowsEquals(() => {
304    for (let x of g()) { throw 42; }
305  }, 42);
306  assertEquals([[]], log);
307
308  log = [];
309  assertThrowsEquals(() => {
310    for (const x of g()) { throw 42; }
311  }, 42);
312  assertEquals([[]], log);
313
314  log = [];
315  assertThrowsEquals(() => {
316    for (x of g()) { throw 42; }
317  }, 42);
318  assertEquals([[]], log);
319
320
321  log = [];
322  assertEquals(42, (() => {
323    for (var x of g()) { return 42; }
324  })());
325  assertEquals([[]], log);
326
327  log = [];
328  assertEquals(42, (() => {
329    for (let x of g()) { return 42; }
330  })());
331  assertEquals([[]], log);
332
333  log = [];
334  assertEquals(42, (() => {
335    for (const x of g()) { return 42; }
336  })());
337  assertEquals([[]], log);
338
339  log = [];
340  assertEquals(42, (() => {
341    for (x of g()) { return 42; }
342  })());
343  assertEquals([[]], log);
344
345
346  log = [];
347  assertEquals(42, eval('for (var x of g()) { x; }'));
348  assertEquals([], log);
349
350  log = [];
351  assertEquals(42, eval('for (let x of g()) { x; }'));
352  assertEquals([], log);
353
354  log = [];
355  assertEquals(42, eval('for (const x of g()) { x; }'));
356  assertEquals([], log);
357
358  log = [];
359  assertEquals(42, eval('for (x of g()) { x; }'));
360  assertEquals([], log);
361
362
363  // Even if doing the assignment throws, still call return
364  log = [];
365  x = { set attr(_) { throw 1234; } };
366  assertThrowsEquals(() => {
367    for (x.attr of g()) { throw 456; }
368  }, 1234);
369  assertEquals([[]], log);
370
371
372  log = [];
373  assertEquals(42, (() => {
374    var [x] = g(); return x;
375  })());
376  assertEquals([[]], log);
377
378  log = [];
379  assertEquals(42, (() => {
380    let [x] = g(); return x;
381  })());
382  assertEquals([[]], log);
383
384  log = [];
385  assertEquals(42, (() => {
386    const [x] = g(); return x;
387  })());
388  assertEquals([[]], log);
389
390  log = [];
391  assertEquals(42, (() => {
392    [x] = g(); return x;
393  })());
394  assertEquals([[]], log);
395
396  log = []
397  assertEquals(42,
398    (([x]) => x)(g())
399  );
400  assertEquals([[]], log);
401
402
403  log = [];
404  assertEquals(42, (() => {
405    var [x,] = g(); return x;
406  })());
407  assertEquals([[]], log);
408
409  log = [];
410  assertEquals(42, (() => {
411    let [x,] = g(); return x;
412  })());
413  assertEquals([[]], log);
414
415  log = [];
416  assertEquals(42, (() => {
417    const [x,] = g(); return x;
418  })());
419  assertEquals([[]], log);
420
421  log = [];
422  assertEquals(42, (() => {
423    [x,] = g(); return x;
424  })());
425  assertEquals([[]], log);
426
427  log = []
428  assertEquals(42,
429    (([x,]) => x)(g())
430  );
431  assertEquals([[]], log);
432
433
434  log = [];
435  assertEquals(42, (() => {
436    var [x,,] = g(); return x;
437  })());
438  assertEquals([], log);
439
440  log = [];
441  assertEquals(42, (() => {
442    let [x,,] = g(); return x;
443  })());
444  assertEquals([], log);
445
446  log = [];
447  assertEquals(42, (() => {
448    const [x,,] = g(); return x;
449  })());
450  assertEquals([], log);
451
452  log = [];
453  assertEquals(42, (() => {
454    [x,,] = g(); return x;
455  })());
456  assertEquals([], log);
457
458  log = []
459  assertEquals(42,
460    (([x,,]) => x)(g())
461  );
462  assertEquals([], log);
463
464
465  log = [];
466  assertEquals([42, undefined], (() => {
467    var [x, y] = g(); return [x, y];
468  })());
469  assertEquals([], log);
470
471  log = [];
472  assertEquals([42, undefined], (() => {
473    let [x, y] = g(); return [x, y];
474  })());
475  assertEquals([], log);
476
477  log = [];
478  assertEquals([42, undefined], (() => {
479    const [x, y] = g(); return [x, y];
480  })());
481  assertEquals([], log);
482
483  log = [];
484  assertEquals([42, undefined], (() => {
485    [x, y] = g(); return [x, y];
486  })());
487  assertEquals([], log);
488
489  log = []
490  assertEquals([42, undefined],
491    (([x, y]) => [x, y])(g())
492  );
493  assertEquals([], log);
494
495
496  log = [];
497  assertEquals([42], (() => {
498    var [...x] = g(); return x;
499  })());
500  assertEquals([], log);
501
502  log = [];
503  assertEquals([42], (() => {
504    let [...x] = g(); return x;
505  })());
506  assertEquals([], log);
507
508  log = [];
509  assertEquals([42], (() => {
510    const [...x] = g(); return x;
511  })());
512  assertEquals([], log);
513
514  log = [];
515  assertEquals([42], (() => {
516    [...x] = g(); return x;
517  })());
518  assertEquals([], log);
519
520  log = []
521  assertEquals([42],
522    (([...x]) => x)(g())
523  );
524  assertEquals([], log);
525
526
527  log = [];
528  assertEquals([42, []], (() => {
529    var [x, ...y] = g(); return [x, y];
530  })());
531  assertEquals([], log);
532
533  log = [];
534  assertEquals([42, []], (() => {
535    let [x, ...y] = g(); return [x, y];
536  })());
537  assertEquals([], log);
538
539  log = [];
540  assertEquals([42, []], (() => {
541    const [x, ...y] = g(); return [x, y];
542  })());
543  assertEquals([], log);
544
545  log = [];
546  assertEquals([42, []], (() => {
547    [x, ...y] = g(); return [x, y];
548  })());
549  assertEquals([], log);
550
551  log = []
552  assertEquals([42, []],
553    (([x, ...y]) => [x, y])(g())
554  );
555  assertEquals([], log);
556
557
558  log = [];
559  assertEquals([], (() => {
560    var [] = g(); return [];
561  })());
562  assertEquals([[]], log);
563
564  log = [];
565  assertEquals([], (() => {
566    let [] = g(); return [];
567  })());
568  assertEquals([[]], log);
569
570  log = [];
571  assertEquals([], (() => {
572    const [] = g(); return [];
573  })());
574  assertEquals([[]], log);
575
576  log = [];
577  assertEquals([], (() => {
578    [] = g(); return [];
579  })());
580  assertEquals([[]], log);
581
582  log = []
583  assertEquals([],
584    (([]) => [])(g())
585  );
586  assertEquals([[]], log);
587
588
589  log = [];
590  assertEquals([], (() => {
591    var [...[]] = g(); return [];
592  })());
593  assertEquals([], log);
594
595  log = [];
596  assertEquals([], (() => {
597    let [...[]] = g(); return [];
598  })());
599  assertEquals([], log);
600
601  log = [];
602  assertEquals([], (() => {
603    const [...[]] = g(); return [];
604  })());
605  assertEquals([], log);
606
607  log = [];
608  assertEquals([], (() => {
609    [...[]] = g(); return [];
610  })());
611  assertEquals([], log);
612
613  log = []
614  assertEquals([],
615    (([...[]]) => [])(g())
616  );
617  assertEquals([], log);
618
619
620  log = [];
621  assertEquals([42], (() => {
622    var [...[x]] = g(); return [x];
623  })());
624  assertEquals([], log);
625
626  log = [];
627  assertEquals([42], (() => {
628    let [...[x]] = g(); return [x];
629  })());
630  assertEquals([], log);
631
632  log = [];
633  assertEquals([42], (() => {
634    const [...[x]] = g(); return [x];
635  })());
636  assertEquals([], log);
637
638  log = [];
639  assertEquals([42], (() => {
640    [...[x]] = g(); return [x];
641  })());
642  assertEquals([], log);
643
644  log = []
645  assertEquals([42],
646    (([...[x]]) => [x])(g())
647  );
648  assertEquals([], log);
649
650
651  log = [];
652  assertEquals([42, undefined], (() => {
653    var [...[x, y]] = g(); return [x, y];
654  })());
655  assertEquals([], log);
656
657  log = [];
658  assertEquals([42, undefined], (() => {
659    let [...[x, y]] = g(); return [x, y];
660  })());
661  assertEquals([], log);
662
663  log = [];
664  assertEquals([42, undefined], (() => {
665    const [...[x, y]] = g(); return [x, y];
666  })());
667  assertEquals([], log);
668
669  log = [];
670  assertEquals([42, undefined], (() => {
671    [...[x, y]] = g(); return [x, y];
672  })());
673  assertEquals([], log);
674
675  log = []
676  assertEquals([42, undefined],
677    (([...[x, y]]) => [x, y])(g())
678  );
679  assertEquals([], log);
680
681
682  log = []
683  assertThrowsEquals(() => {
684    let x = { set foo(_) { throw 666; } };
685    [x.foo] = g();
686  }, 666);
687  assertEquals([[]], log);
688
689
690  log = []
691  assertThrows(() => {
692    var [[]] = g();
693  }, TypeError);
694  assertEquals([[]], log);
695
696  log = []
697  assertThrows(() => {
698    let [[]] = g();
699  }, TypeError);
700  assertEquals([[]], log);
701
702  log = []
703  assertThrows(() => {
704    const [[]] = g();
705  }, TypeError);
706  assertEquals([[]], log);
707
708  log = []
709  assertThrows(() => {
710    [[]] = g();
711  }, TypeError);
712  assertEquals([[]], log);
713
714  log = []
715  assertThrows(() => {
716    (([[]]) => 0)(g());
717  }, TypeError);
718  assertEquals([[]], log);
719
720
721  log = []
722  assertThrows(() => {
723    var [...[[]]] = g();
724  }, TypeError);
725  assertEquals([], log);
726
727  log = []
728  assertThrows(() => {
729    let [...[[]]] = g();
730  }, TypeError);
731  assertEquals([], log);
732
733  log = []
734  assertThrows(() => {
735    const [...[[]]] = g();
736  }, TypeError);
737  assertEquals([], log);
738
739  log = []
740  assertThrows(() => {
741    [...[[]]] = g();
742  }, TypeError);
743  assertEquals([], log);
744
745  log = []
746  assertThrows(() => {
747    (([...[[]]]) => 0)(g());
748  }, TypeError);
749  assertEquals([], log);
750
751
752  {
753    let backup = Array.prototype[Symbol.iterator];
754    Array.prototype[Symbol.iterator] = () => g();
755
756
757    log = [];
758    assertDoesNotThrow(() => {
759      var [x, ...[y]] = [1, 2, 3]
760    });
761    assertEquals(log, [[]]);
762
763    log = [];
764    assertDoesNotThrow(() => {
765      let [x, ...[y]] = [1, 2, 3];
766    });
767    assertEquals(log, [[]]);
768
769    log = [];
770    assertDoesNotThrow(() => {
771      const [x, ...[y]] = [1, 2, 3];
772    });
773    assertEquals(log, [[]]);
774
775    log = [];
776    assertDoesNotThrow(() => {
777      (([x, ...[y]]) => {})([1, 2, 3]);
778    });
779    assertEquals(log, [[]]);
780
781
782    log = [];
783    assertThrows(() => {
784      var [x, ...[[]]] = [1, 2, 3];
785    }, TypeError);
786    assertEquals(log, [[]]);
787
788    log = [];
789    assertThrows(() => {
790      let [x, ...[[]]] = [1, 2, 3];
791    }, TypeError);
792    assertEquals(log, [[]]);
793
794    log = [];
795    assertThrows(() => {
796      const [x, ...[[]]] = [1, 2, 3];
797    }, TypeError);
798    assertEquals(log, [[]]);
799
800    log = [];
801    assertThrows(() => {
802      (([x, ...[[]]]) => {})([1, 2, 3]);
803    }, TypeError);
804    assertEquals(log, [[]]);
805
806
807    log = [];
808    assertDoesNotThrow(() => {
809      var [x, ...[...y]] = [1, 2, 3];
810    });
811    assertEquals(log, []);
812
813    log = [];
814    assertDoesNotThrow(() => {
815      let [x, ...[...y]] = [1, 2, 3];
816    });
817    assertEquals(log, []);
818
819    log = [];
820    assertDoesNotThrow(() => {
821      const [x, ...[...y]] = [1, 2, 3];
822    });
823    assertEquals(log, []);
824
825    log = [];
826    assertDoesNotThrow(() => {
827      (([x, ...[...y]]) => {})([1, 2, 3]);
828    });
829    assertEquals(log, []);
830
831
832    Array.prototype[Symbol.iterator] = backup;
833  }
834}
835
836
837// Return method throws.
838{
839  let log = [];
840  g.prototype.return = (...args) => { log.push(args); throw 23 };
841
842
843  log = [];
844  assertThrowsEquals(() => {
845    for (var x of g()) { break; }
846  }, 23);
847  assertEquals([[]], log);
848
849  log = [];
850  assertThrowsEquals(() => {
851    for (let x of g()) { break; }
852  }, 23);
853  assertEquals([[]], log);
854
855  log = [];
856  assertThrowsEquals(() => {
857    for (const x of g()) { break; }
858  }, 23);
859  assertEquals([[]], log);
860
861  log = [];
862  assertThrowsEquals(() => {
863    for (x of g()) { break; }
864  }, 23);
865  assertEquals([[]], log);
866
867
868  log = [];
869  assertThrowsEquals(() => {
870    for (var x of g()) { throw 42; }
871  }, 42);
872  assertEquals([[]], log);
873
874  log = [];
875  assertThrowsEquals(() => {
876    for (let x of g()) { throw 42; }
877  }, 42);
878  assertEquals([[]], log);
879
880  log = [];
881  assertThrowsEquals(() => {
882    for (const x of g()) { throw 42; }
883  }, 42);
884  assertEquals([[]], log);
885
886  log = [];
887  assertThrowsEquals(() => {
888    for (x of g()) { throw 42; }
889  }, 42);
890  assertEquals([[]], log);
891
892
893  log = [];
894  assertThrowsEquals(() => {
895    for (var x of g()) { return 42; }
896  }, 23);
897  assertEquals([[]], log);
898
899  log = [];
900  assertThrowsEquals(() => {
901    for (let x of g()) { return 42; }
902  }, 23);
903  assertEquals([[]], log);
904
905  log = [];
906  assertThrowsEquals(() => {
907    for (const x of g()) { return 42; }
908  }, 23);
909  assertEquals([[]], log);
910
911  log = [];
912  assertThrowsEquals(() => {
913    for (x of g()) { return 42; }
914  }, 23);
915  assertEquals([[]], log);
916
917
918  log = [];
919  assertEquals(42, eval('for (var x of g()) { x; }'));
920  assertEquals([], log);
921
922  log = [];
923  assertEquals(42, eval('for (let x of g()) { x; }'));
924  assertEquals([], log);
925
926  log = [];
927  assertEquals(42, eval('for (const x of g()) { x; }'));
928  assertEquals([], log);
929
930  log = [];
931  assertEquals(42, eval('for (x of g()) { x; }'));
932  assertEquals([], log);
933
934
935  log = [];
936  assertThrowsEquals(() => {
937    var [x] = g(); return x;
938  }, 23);
939  assertEquals([[]], log);
940
941  log = [];
942  assertThrowsEquals(() => {
943    let [x] = g(); return x;
944  }, 23);
945  assertEquals([[]], log);
946
947  log = [];
948  assertThrowsEquals(() => {
949    const [x] = g(); return x;
950  }, 23);
951  assertEquals([[]], log);
952
953  log = [];
954  assertThrowsEquals(() => {
955    [x] = g(); return x;
956  }, 23);
957  assertEquals([[]], log);
958
959  log = [];
960  assertThrowsEquals(() => {
961    (([x]) => x)(g())
962  }, 23);
963  assertEquals([[]], log);
964}
965
966
967// Next method throws.
968{
969  g.prototype.next = () => { throw 666; };
970  g.prototype.return = () => { assertUnreachable() };
971
972
973  assertThrowsEquals(() => {
974    for (var x of g()) {}
975  }, 666);
976
977  assertThrowsEquals(() => {
978    for (let x of g()) {}
979  }, 666);
980
981  assertThrowsEquals(() => {
982    for (const x of g()) {}
983  }, 666);
984
985  assertThrowsEquals(() => {
986    for (x of g()) {}
987  }, 666);
988
989  assertThrowsEquals(() => {
990    var [x] = g();
991  }, 666);
992
993  assertThrowsEquals(() => {
994    let [x] = g();
995  }, 666);
996
997  assertThrowsEquals(() => {
998    const [x] = g();
999  }, 666);
1000
1001  assertThrowsEquals(() => {
1002    [x] = g();
1003  }, 666);
1004
1005  assertThrowsEquals(() => {
1006    (([x]) => x)(g());
1007  }, 666);
1008
1009  assertThrowsEquals(() => {
1010    var [...x] = g();
1011  }, 666);
1012
1013  assertThrowsEquals(() => {
1014    let [...x] = g();
1015  }, 666);
1016
1017  assertThrowsEquals(() => {
1018    const [...x] = g();
1019  }, 666);
1020
1021  assertThrowsEquals(() => {
1022    [...x] = g();
1023  }, 666);
1024
1025  assertThrowsEquals(() => {
1026    (([...x]) => x)(g());
1027  }, 666);
1028}
1029
1030
1031// Value throws.
1032{
1033  g.prototype.next = () => ({get value() {throw 666}});
1034  g.prototype.return = () => { assertUnreachable() };
1035
1036
1037  assertThrowsEquals(() => {
1038    for (var x of g()) {}
1039  }, 666);
1040
1041  assertThrowsEquals(() => {
1042    for (let x of g()) {}
1043  }, 666);
1044
1045  assertThrowsEquals(() => {
1046    for (const x of g()) {}
1047  }, 666);
1048
1049  assertThrowsEquals(() => {
1050    for (x of g()) {}
1051  }, 666);
1052
1053  assertThrowsEquals(() => {
1054    var [x] = g();
1055  }, 666);
1056
1057  assertThrowsEquals(() => {
1058    let [x] = g();
1059  }, 666);
1060
1061  assertThrowsEquals(() => {
1062    const [x] = g();
1063  }, 666);
1064
1065  assertThrowsEquals(() => {
1066    [x] = g();
1067  }, 666);
1068
1069  assertThrowsEquals(() => {
1070    (([x]) => x)(g());
1071  }, 666);
1072
1073  assertThrowsEquals(() => {
1074    var [...x] = g();
1075  }, 666);
1076
1077  assertThrowsEquals(() => {
1078    let [...x] = g();
1079  }, 666);
1080
1081  assertThrowsEquals(() => {
1082    const [...x] = g();
1083  }, 666);
1084
1085  assertThrowsEquals(() => {
1086    [...x] = g();
1087  }, 666);
1088
1089  assertThrowsEquals(() => {
1090    (([...x]) => x)(g());
1091  }, 666);
1092}
1093
1094
1095// Done throws.
1096{
1097  g.prototype.next = () => ({get done() {throw 666}});
1098  g.prototype.return = () => { assertUnreachable() };
1099
1100
1101  assertThrowsEquals(() => {
1102    for (var x of g()) {}
1103  }, 666);
1104
1105  assertThrowsEquals(() => {
1106    for (let x of g()) {}
1107  }, 666);
1108
1109  assertThrowsEquals(() => {
1110    for (const x of g()) {}
1111  }, 666);
1112
1113  assertThrowsEquals(() => {
1114    for (x of g()) {}
1115  }, 666);
1116
1117  assertThrowsEquals(() => {
1118    var [x] = g();
1119  }, 666);
1120
1121  assertThrowsEquals(() => {
1122    let [x] = g();
1123  }, 666);
1124
1125  assertThrowsEquals(() => {
1126    const [x] = g();
1127  }, 666);
1128
1129  assertThrowsEquals(() => {
1130    [x] = g();
1131  }, 666);
1132
1133  assertThrowsEquals(() => {
1134    (([x]) => x)(g());
1135  }, 666);
1136
1137  assertThrowsEquals(() => {
1138    var [...x] = g();
1139  }, 666);
1140
1141  assertThrowsEquals(() => {
1142    let [...x] = g();
1143  }, 666);
1144
1145  assertThrowsEquals(() => {
1146    const [...x] = g();
1147  }, 666);
1148
1149  assertThrowsEquals(() => {
1150    [...x] = g();
1151  }, 666);
1152
1153  assertThrowsEquals(() => {
1154    (([...x]) => x)(g());
1155  }, 666);
1156}
1157
1158
1159// Nested loops.
1160{
1161  function* g1() { yield 1; yield 2; throw 3; }
1162  function* g2() { yield -1; yield -2; throw -3; }
1163
1164  assertDoesNotThrow(() => {
1165    for (let x of g1()) {
1166      for (let y of g2()) {
1167        if (y == -2) break;
1168      }
1169      if (x == 2) break;
1170    }
1171  }, -3);
1172
1173  assertThrowsEquals(() => {
1174    for (let x of g1()) {
1175      for (let y of g2()) {
1176      }
1177    }
1178  }, -3);
1179
1180  assertThrowsEquals(() => {
1181    for (let x of g1()) {
1182      for (let y of g2()) {
1183        if (y == -2) break;
1184      }
1185    }
1186  }, 3);
1187
1188  assertDoesNotThrow(() => {
1189    l: for (let x of g1()) {
1190      for (let y of g2()) {
1191        if (y == -2) break l;
1192      }
1193    }
1194  });
1195
1196  assertThrowsEquals(() => {
1197    for (let x of g1()) {
1198      for (let y of g2()) {
1199        throw 4;
1200      }
1201    }
1202  }, 4);
1203
1204  assertThrowsEquals(() => {
1205    for (let x of g1()) {
1206      for (let y of g2()) {
1207        if (y == -2) throw 4;
1208      }
1209    }
1210  }, 4);
1211
1212  let log = [];
1213  g1.prototype.return = () => { log.push(1); throw 5 };
1214  g2.prototype.return = () => { log.push(2); throw -5 };
1215
1216  log = [];
1217  assertThrowsEquals(() => {
1218    for (let x of g1()) {
1219      for (let y of g2()) {
1220        if (y == -2) break;
1221      }
1222      if (x == 2) break;
1223    }
1224  }, -5);
1225  assertEquals([2, 1], log);
1226
1227  log = [];
1228  assertThrowsEquals(() => {
1229    for (let x of g1()) {
1230      for (let y of g2()) {
1231      }
1232    }
1233  }, -3);
1234  assertEquals([1], log);
1235
1236  log = [];
1237  assertThrowsEquals(() => {
1238    for (let x of g1()) {
1239      for (let y of g2()) {
1240        if (y == -2) break;
1241      }
1242    }
1243  }, -5);
1244  assertEquals([2, 1], log);
1245
1246  log = [];
1247  assertThrowsEquals(() => {
1248    l: for (let x of g1()) {
1249      for (let y of g2()) {
1250        if (y == -2) break l;
1251      }
1252    }
1253  }, -5);
1254  assertEquals([2, 1], log);
1255
1256  log = [];
1257  assertThrowsEquals(() => {
1258    for (let x of g1()) {
1259      for (let y of g2()) {
1260        throw 4;
1261      }
1262    }
1263  }, 4);
1264  assertEquals([2, 1], log);
1265
1266  log = [];
1267  assertThrowsEquals(() => {
1268    for (let x of g1()) {
1269      for (let y of g2()) {
1270        if (y == -2) throw 4;
1271      }
1272    }
1273  }, 4);
1274  assertEquals([2, 1], log);
1275
1276  log = [];
1277  assertThrowsEquals(() => {
1278    for (let x of g1()) {
1279      try {
1280        for (let y of g2()) {
1281        }
1282      } catch (_) {}
1283    }
1284  }, 3);
1285  assertEquals([], log);
1286
1287  log = [];
1288  assertThrowsEquals(() => {
1289    for (let x of g1()) {
1290      try {
1291        for (let y of g2()) {
1292        }
1293      } catch (_) {}
1294      if (x == 2) break;
1295    }
1296  }, 5);
1297  assertEquals([1], log);
1298}
1299
1300
1301// yield*, argument's return method is "undefined".
1302function TestYieldStarWithoutReturn(get_iterable) {
1303  assertTrue(get_iterable().return == undefined);
1304
1305  function* g() { yield* get_iterable() }
1306
1307  {
1308    let gen = g();
1309    assertEquals({value: 1, done: false}, gen.next());
1310    assertEquals({value: undefined, done: true}, gen.return());
1311  }
1312
1313  assertEquals(42, (() => {
1314    for (let x of g()) break;
1315    return 42;
1316  })());
1317
1318  assertEquals(42, (() => {
1319    for (let x of g()) return 42;
1320  })());
1321
1322  assertThrowsEquals(() => {
1323    for (let x of g()) throw 42;
1324  }, 42);
1325}
1326{
1327  let get_iterable1 = () => [1, 2];
1328  let get_iterable2 = function*() { yield 1; yield 2 };
1329  get_iterable2.prototype.return = null;
1330  TestYieldStarWithoutReturn(get_iterable1);
1331  TestYieldStarWithoutReturn(get_iterable2);
1332}
1333
1334
1335// yield*, argument's return method is defined.
1336{
1337  let get_iterable = function*() { yield 1; yield 2 };
1338  const obj = {};
1339  get_iterable.prototype.return = (...args) => obj;
1340
1341  function* g() { yield* get_iterable() }
1342
1343  {
1344    let gen = g();
1345    assertEquals({value: 1, done: false}, gen.next());
1346    assertSame(obj, gen.return());
1347    assertSame(obj, gen.return());
1348    assertSame(obj, gen.return());
1349    assertEquals({value: 2, done: false}, gen.next());
1350    assertSame(obj, gen.return());
1351    assertSame(obj, gen.return());
1352    assertSame(obj, gen.return());
1353    assertEquals({value: undefined, done: true}, gen.next());
1354    assertEquals({value: undefined, done: true}, gen.return());
1355    assertEquals({value: undefined, done: true}, gen.return());
1356  }
1357
1358  assertEquals(42, (() => {
1359    for (let x of g()) break;
1360    return 42;
1361  })());
1362
1363  assertEquals(42, (() => {
1364    for (let x of g()) return 42;
1365  })());
1366
1367  assertThrowsEquals(() => {
1368    for (let x of g()) throw 42;
1369  }, 42);
1370}
1371