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 6 function* 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". 1302 function 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