Changeset 207228 in webkit
- Timestamp:
- Oct 12, 2016 11:47:48 AM (8 years ago)
- Location:
- trunk
- Files:
-
- 15 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r207217 r207228 1 2016-10-12 Joseph Pecoraro <pecoraro@apple.com> 2 3 Emit DebugHooks uniformly with pause locations instead of having separate pause locations and op_debug emits 4 https://bugs.webkit.org/show_bug.cgi?id=162809 5 6 Reviewed by Geoffrey Garen. 7 8 * inspector/debugger/stepping/stepping-control-flow-expected.txt: 9 * inspector/debugger/stepping/stepping-control-flow.html: 10 Add new tests for stepping through conditional expressions with constants, 11 logical operations, binary operations, and unary negations. 12 13 * inspector/debugger/stepping/stepping-loops-expected.txt: 14 * inspector/debugger/stepping/stepping-loops.html: 15 Update tests for changes in stepping behavior in for loops. 16 1 17 2016-10-12 Carlos Alberto Lopez Perez <clopez@igalia.com> 2 18 -
trunk/LayoutTests/inspector/debugger/stepping/stepping-control-flow-expected.txt
r206652 r207228 8 8 PAUSED (debugger-statement) 9 9 PAUSE AT entryIfSingleStatement:16:5 10 12 }10 12 11 11 13 12 12 14 function entryIfSingleStatement() { 13 13 -> 15 |debugger; 14 16 if (tru e)14 16 if (truthy) 15 15 17 a(); 16 18 if (false )16 18 if (falsey) 17 17 18 18 ACTION: step-over … … 21 21 14 function entryIfSingleStatement() { 22 22 15 debugger; 23 -> 16 if (|tru e)23 -> 16 if (|truthy) 24 24 17 a(); 25 18 if (false )25 18 if (falsey) 26 26 19 a(); 27 27 … … 30 30 14 function entryIfSingleStatement() { 31 31 15 debugger; 32 16 if (tru e)32 16 if (truthy) 33 33 -> 17 |a(); 34 18 if (false )34 18 if (falsey) 35 35 19 a(); 36 36 20 } … … 39 39 PAUSE AT entryIfSingleStatement:19:9 40 40 15 debugger; 41 16 if (tru e)41 16 if (truthy) 42 42 17 a(); 43 -> 18 if (|false )43 -> 18 if (|falsey) 44 44 19 a(); 45 45 20 } … … 49 49 PAUSE AT entryIfSingleStatement:21:2 50 50 17 a(); 51 18 if (false )51 18 if (falsey) 52 52 19 a(); 53 53 -> 20 }| … … 69 69 22 function entryIfMultiStatement() { 70 70 -> 23 |debugger; 71 24 if (tru e) {71 24 if (truthy) { 72 72 25 a(); 73 73 26 a(); … … 78 78 22 function entryIfMultiStatement() { 79 79 23 debugger; 80 -> 24 if (|tru e) {80 -> 24 if (|truthy) { 81 81 25 a(); 82 82 26 a(); … … 87 87 22 function entryIfMultiStatement() { 88 88 23 debugger; 89 24 if (tru e) {89 24 if (truthy) { 90 90 -> 25 |a(); 91 91 26 a(); 92 92 27 } 93 28 if (false ) {93 28 if (falsey) { 94 94 95 95 ACTION: step-over 96 96 PAUSE AT entryIfMultiStatement:27:9 97 97 23 debugger; 98 24 if (tru e) {98 24 if (truthy) { 99 99 25 a(); 100 100 -> 26 |a(); 101 101 27 } 102 28 if (false ) {102 28 if (falsey) { 103 103 29 a(); 104 104 … … 108 108 26 a(); 109 109 27 } 110 -> 28 if (|false ) {110 -> 28 if (|falsey) { 111 111 29 a(); 112 112 30 a(); … … 136 136 34 function entryIfElse() { 137 137 -> 35 |debugger; 138 36 if (tru e)138 36 if (truthy) 139 139 37 a(); 140 140 38 else … … 145 145 34 function entryIfElse() { 146 146 35 debugger; 147 -> 36 if (|tru e)147 -> 36 if (|truthy) 148 148 37 a(); 149 149 38 else … … 154 154 34 function entryIfElse() { 155 155 35 debugger; 156 36 if (tru e)156 36 if (truthy) 157 157 -> 37 |a(); 158 158 38 else 159 159 39 a(); 160 40 if (false )160 40 if (falsey) 161 161 162 162 ACTION: step-over … … 165 165 38 else 166 166 39 a(); 167 -> 40 if (|false )167 -> 40 if (|falsey) 168 168 41 a(); 169 169 42 else … … 172 172 ACTION: step-over 173 173 PAUSE AT entryIfElse:44:9 174 40 if (false )174 40 if (falsey) 175 175 41 a(); 176 176 42 else … … 203 203 46 function entryIfElseChain() { 204 204 -> 47 |debugger; 205 48 if (false )205 48 if (falsey) 206 206 49 a(); 207 50 else if (tru e)207 50 else if (truthy) 208 208 209 209 ACTION: step-over … … 212 212 46 function entryIfElseChain() { 213 213 47 debugger; 214 -> 48 if (|false )214 -> 48 if (|falsey) 215 215 49 a(); 216 50 else if (tru e)216 50 else if (truthy) 217 217 51 a(); 218 218 … … 220 220 PAUSE AT entryIfElseChain:51:14 221 221 47 debugger; 222 48 if (false )222 48 if (falsey) 223 223 49 a(); 224 -> 50 else if (|tru e)224 -> 50 else if (|truthy) 225 225 51 a(); 226 226 52 else … … 229 229 ACTION: step-over 230 230 PAUSE AT entryIfElseChain:52:9 231 48 if (false )231 48 if (falsey) 232 232 49 a(); 233 50 else if (tru e)233 50 else if (truthy) 234 234 -> 51 |a(); 235 235 52 else … … 242 242 53 a(); 243 243 54 244 -> 55 if (|false )244 -> 55 if (|falsey) 245 245 56 a(); 246 57 else if (false )246 57 else if (falsey) 247 247 58 a(); 248 248 … … 250 250 PAUSE AT entryIfElseChain:58:14 251 251 54 252 55 if (false )252 55 if (falsey) 253 253 56 a(); 254 -> 57 else if (|false )254 -> 57 else if (|falsey) 255 255 58 a(); 256 256 59 else … … 259 259 ACTION: step-over 260 260 PAUSE AT entryIfElseChain:61:9 261 57 else if (false )261 57 else if (falsey) 262 262 58 a(); 263 263 59 else … … 322 322 68 323 323 69 function entryTernary() { 324 70 let t = () => tru e;324 70 let t = () => truthy; 325 325 326 326 ACTION: resume … … 352 352 353 353 ACTION: step-in 354 PAUSE AT a: 8:5355 4 <script src="../resources/log-pause-location.js"></script>356 5 <script>357 6 function a() {358 -> 7 |return 1;359 8}360 9361 1 0 function b() {354 PAUSE AT a:11:16 355 7 var value = 1; 356 8 var truthy = true; 357 9 var falsey = false; 358 -> 10 function a() { |return value; } 359 11 function b() { return value; } 360 12 361 13 362 362 363 363 ACTION: step-out … … 372 372 373 373 ACTION: step-in 374 PAUSE AT a: 8:5375 4 <script src="../resources/log-pause-location.js"></script>376 5 <script>377 6 function a() {378 -> 7 |return 1;379 8}380 9381 1 0 function b() {374 PAUSE AT a:11:16 375 7 var value = 1; 376 8 var truthy = true; 377 9 var falsey = false; 378 -> 10 function a() { |return value; } 379 11 function b() { return value; } 380 12 381 13 382 382 383 383 ACTION: step-out … … 399 399 68 400 400 69 function entryTernary() { 401 70 let t = () => tru e;401 70 let t = () => truthy; 402 402 403 403 ACTION: resume … … 411 411 PAUSE AT entryTernary:73:5 412 412 69 function entryTernary() { 413 70 let t = () => tru e;414 71 let f = () => false ;413 70 let t = () => truthy; 414 71 let f = () => falsey; 415 415 -> 72 |debugger; 416 416 73 let x = t() ? a() : b(); … … 420 420 ACTION: step-over 421 421 PAUSE AT entryTernary:74:5 422 70 let t = () => tru e;423 71 let f = () => false ;422 70 let t = () => truthy; 423 71 let f = () => falsey; 424 424 72 debugger; 425 425 -> 73 |let x = t() ? a() : b(); … … 430 430 ACTION: step-over 431 431 PAUSE AT entryTernary:75:5 432 71 let f = () => false ;432 71 let f = () => falsey; 433 433 72 debugger; 434 434 73 let x = t() ? a() : b(); … … 436 436 75 } 437 437 76 438 77 // ---------438 77 function entryIfConstantBranch() { 439 439 440 440 ACTION: step-over … … 445 445 -> 75 }| 446 446 76 447 77 // ---------448 78 447 77 function entryIfConstantBranch() { 448 78 debugger; 449 449 450 450 ACTION: resume … … 458 458 PAUSE AT entryTernary:73:5 459 459 69 function entryTernary() { 460 70 let t = () => tru e;461 71 let f = () => false ;460 70 let t = () => truthy; 461 71 let f = () => falsey; 462 462 -> 72 |debugger; 463 463 73 let x = t() ? a() : b(); … … 467 467 ACTION: step-over 468 468 PAUSE AT entryTernary:74:5 469 70 let t = () => tru e;470 71 let f = () => false ;469 70 let t = () => truthy; 470 71 let f = () => falsey; 471 471 72 debugger; 472 472 -> 73 |let x = t() ? a() : b(); … … 480 480 68 481 481 69 function entryTernary() { 482 -> 70 let t = () => |tru e;483 71 let f = () => false ;482 -> 70 let t = () => |truthy; 483 71 let f = () => falsey; 484 484 72 debugger; 485 485 73 let x = t() ? a() : b(); … … 487 487 ACTION: step-out 488 488 PAUSE AT entryTernary:74:19 489 70 let t = () => tru e;490 71 let f = () => false ;489 70 let t = () => truthy; 490 71 let f = () => falsey; 491 491 72 debugger; 492 492 -> 73 let x = t() ? |a() : b(); … … 496 496 497 497 ACTION: step-in 498 PAUSE AT a: 8:5499 4 <script src="../resources/log-pause-location.js"></script>500 5 <script>501 6 function a() {502 -> 7 |return 1;503 8}504 9505 1 0 function b() {498 PAUSE AT a:11:16 499 7 var value = 1; 500 8 var truthy = true; 501 9 var falsey = false; 502 -> 10 function a() { |return value; } 503 11 function b() { return value; } 504 12 505 13 506 506 507 507 ACTION: step-out 508 508 PAUSE AT entryTernary:75:5 509 71 let f = () => false ;509 71 let f = () => falsey; 510 510 72 debugger; 511 511 73 let x = t() ? a() : b(); … … 513 513 75 } 514 514 76 515 77 // ---------515 77 function entryIfConstantBranch() { 516 516 517 517 ACTION: step-in … … 519 519 68 520 520 69 function entryTernary() { 521 70 let t = () => tru e;522 -> 71 let f = () => |false ;521 70 let t = () => truthy; 522 -> 71 let f = () => |falsey; 523 523 72 debugger; 524 524 73 let x = t() ? a() : b(); … … 527 527 ACTION: step-out 528 528 PAUSE AT entryTernary:75:25 529 71 let f = () => false ;529 71 let f = () => falsey; 530 530 72 debugger; 531 531 73 let x = t() ? a() : b(); … … 533 533 75 } 534 534 76 535 77 // ---------536 537 ACTION: step-in 538 PAUSE AT b:12: 5539 8 }540 9 541 10 function b() {542 -> 11 |return 2;543 12 }535 77 function entryIfConstantBranch() { 536 537 ACTION: step-in 538 PAUSE AT b:12:16 539 8 var truthy = true; 540 9 var falsey = false; 541 10 function a() { return value; } 542 -> 11 function b() { |return value; } 543 12 544 544 13 545 545 14 function entryIfSingleStatement() { … … 552 552 -> 75 }| 553 553 76 554 77 // --------- 555 78 556 557 ACTION: resume 558 RESUMED 559 PASS: Should have used all steps. 560 554 77 function entryIfConstantBranch() { 555 78 debugger; 556 557 ACTION: resume 558 RESUMED 559 PASS: Should have used all steps. 560 561 -- Running test case: Debugger.stepping.ConstantBranch 562 EXPRESSION: setTimeout(entryIfConstantBranch) 563 STEPS: over, over, over, over, over, over, resume 564 PAUSED (debugger-statement) 565 PAUSE AT entryIfConstantBranch:79:5 566 75 } 567 76 568 77 function entryIfConstantBranch() { 569 -> 78 |debugger; 570 79 if (true) 571 80 a(); 572 81 if (false) 573 574 ACTION: step-over 575 PAUSE AT entryIfConstantBranch:80:9 576 76 577 77 function entryIfConstantBranch() { 578 78 debugger; 579 -> 79 if (|true) 580 80 a(); 581 81 if (false) 582 82 a(); 583 584 ACTION: step-over 585 PAUSE AT entryIfConstantBranch:81:9 586 77 function entryIfConstantBranch() { 587 78 debugger; 588 79 if (true) 589 -> 80 |a(); 590 81 if (false) 591 82 a(); 592 83 if (0) 593 594 ACTION: step-over 595 PAUSE AT entryIfConstantBranch:82:9 596 78 debugger; 597 79 if (true) 598 80 a(); 599 -> 81 if (|false) 600 82 a(); 601 83 if (0) 602 84 a(); 603 604 ACTION: step-over 605 PAUSE AT entryIfConstantBranch:84:9 606 80 a(); 607 81 if (false) 608 82 a(); 609 -> 83 if (|0) 610 84 a(); 611 85 if (null) 612 86 a(); 613 614 ACTION: step-over 615 PAUSE AT entryIfConstantBranch:86:9 616 82 a(); 617 83 if (0) 618 84 a(); 619 -> 85 if (|null) 620 86 a(); 621 87 } 622 88 623 624 ACTION: step-over 625 PAUSE AT entryIfConstantBranch:88:2 626 84 a(); 627 85 if (null) 628 86 a(); 629 -> 87 }| 630 88 631 89 function entryIfWithLogicalOperation() { 632 90 debugger; 633 634 ACTION: resume 635 RESUMED 636 PASS: Should have used all steps. 637 638 -- Running test case: Debugger.stepping.IfWithLogicalOperation 639 EXPRESSION: setTimeout(entryIfWithLogicalOperation) 640 STEPS: over, in, out, in, out, over, resume 641 PAUSED (debugger-statement) 642 PAUSE AT entryIfWithLogicalOperation:91:5 643 87 } 644 88 645 89 function entryIfWithLogicalOperation() { 646 -> 90 |debugger; 647 91 if (true && a() && a()) 648 92 b(); 649 93 } 650 651 ACTION: step-over 652 PAUSE AT entryIfWithLogicalOperation:92:9 653 88 654 89 function entryIfWithLogicalOperation() { 655 90 debugger; 656 -> 91 if (|true && a() && a()) 657 92 b(); 658 93 } 659 94 660 661 ACTION: step-in 662 PAUSE AT a:11:16 663 7 var value = 1; 664 8 var truthy = true; 665 9 var falsey = false; 666 -> 10 function a() { |return value; } 667 11 function b() { return value; } 668 12 669 13 670 671 ACTION: step-out 672 PAUSE AT entryIfWithLogicalOperation:92:24 673 88 674 89 function entryIfWithLogicalOperation() { 675 90 debugger; 676 -> 91 if (true && a() && |a()) 677 92 b(); 678 93 } 679 94 680 681 ACTION: step-in 682 PAUSE AT a:11:16 683 7 var value = 1; 684 8 var truthy = true; 685 9 var falsey = false; 686 -> 10 function a() { |return value; } 687 11 function b() { return value; } 688 12 689 13 690 691 ACTION: step-out 692 PAUSE AT entryIfWithLogicalOperation:93:9 693 89 function entryIfWithLogicalOperation() { 694 90 debugger; 695 91 if (true && a() && a()) 696 -> 92 |b(); 697 93 } 698 94 699 95 function entryIfWithBinaryOperation() { 700 701 ACTION: step-over 702 PAUSE AT entryIfWithLogicalOperation:94:2 703 90 debugger; 704 91 if (true && a() && a()) 705 92 b(); 706 -> 93 }| 707 94 708 95 function entryIfWithBinaryOperation() { 709 96 let i = a(); 710 711 ACTION: resume 712 RESUMED 713 PASS: Should have used all steps. 714 715 -- Running test case: Debugger.stepping.IfWithBinaryOperation 716 EXPRESSION: setTimeout(entryIfWithBinaryOperation) 717 STEPS: over, in, over, resume 718 PAUSED (debugger-statement) 719 PAUSE AT entryIfWithBinaryOperation:98:5 720 94 721 95 function entryIfWithBinaryOperation() { 722 96 let i = a(); 723 -> 97 |debugger; 724 98 if (i < 2) 725 99 b(); 726 100 } 727 728 ACTION: step-over 729 PAUSE AT entryIfWithBinaryOperation:99:9 730 95 function entryIfWithBinaryOperation() { 731 96 let i = a(); 732 97 debugger; 733 -> 98 if (|i < 2) 734 99 b(); 735 100 } 736 101 737 738 ACTION: step-in 739 PAUSE AT entryIfWithBinaryOperation:100:9 740 96 let i = a(); 741 97 debugger; 742 98 if (i < 2) 743 -> 99 |b(); 744 100 } 745 101 746 102 function entryIfWithNotOperation() { 747 748 ACTION: step-over 749 PAUSE AT entryIfWithBinaryOperation:101:2 750 97 debugger; 751 98 if (i < 2) 752 99 b(); 753 -> 100 }| 754 101 755 102 function entryIfWithNotOperation() { 756 103 debugger; 757 758 ACTION: resume 759 RESUMED 760 PASS: Should have used all steps. 761 762 -- Running test case: Debugger.stepping.IfWithNotOperation 763 EXPRESSION: setTimeout(entryIfWithNotOperation) 764 STEPS: over, in, over, in, over, resume 765 PAUSED (debugger-statement) 766 PAUSE AT entryIfWithNotOperation:104:5 767 100 } 768 101 769 102 function entryIfWithNotOperation() { 770 -> 103 |debugger; 771 104 if (!false) 772 105 a(); 773 106 if (!!true) 774 775 ACTION: step-over 776 PAUSE AT entryIfWithNotOperation:105:9 777 101 778 102 function entryIfWithNotOperation() { 779 103 debugger; 780 -> 104 if (|!false) 781 105 a(); 782 106 if (!!true) 783 107 a(); 784 785 ACTION: step-in 786 PAUSE AT entryIfWithNotOperation:106:9 787 102 function entryIfWithNotOperation() { 788 103 debugger; 789 104 if (!false) 790 -> 105 |a(); 791 106 if (!!true) 792 107 a(); 793 108 } 794 795 ACTION: step-over 796 PAUSE AT entryIfWithNotOperation:107:9 797 103 debugger; 798 104 if (!false) 799 105 a(); 800 -> 106 if (|!!true) 801 107 a(); 802 108 } 803 109 804 805 ACTION: step-in 806 PAUSE AT entryIfWithNotOperation:108:9 807 104 if (!false) 808 105 a(); 809 106 if (!!true) 810 -> 107 |a(); 811 108 } 812 109 813 110 // --------- 814 815 ACTION: step-over 816 PAUSE AT entryIfWithNotOperation:109:2 817 105 a(); 818 106 if (!!true) 819 107 a(); 820 -> 108 }| 821 109 822 110 // --------- 823 111 824 825 ACTION: resume 826 RESUMED 827 PASS: Should have used all steps. 828 -
trunk/LayoutTests/inspector/debugger/stepping/stepping-control-flow.html
r206652 r207228 5 5 <script src="../resources/log-pause-location.js"></script> 6 6 <script> 7 function a() { 8 return1;9 } 10 11 function b() {12 return 2; 13 } 7 // We may want to allow constants to eliminate branches. Use vars for existing tests and have constant specific tests. 8 var value = 1; 9 var truthy = true; 10 var falsey = false; 11 function a() { return value; } 12 function b() { return value; } 13 14 14 15 15 function entryIfSingleStatement() { 16 16 debugger; 17 if (tru e)18 a(); 19 if (false )17 if (truthy) 18 a(); 19 if (falsey) 20 20 a(); 21 21 } … … 23 23 function entryIfMultiStatement() { 24 24 debugger; 25 if (tru e) {25 if (truthy) { 26 26 a(); 27 27 a(); 28 28 } 29 if (false ) {29 if (falsey) { 30 30 a(); 31 31 a(); … … 35 35 function entryIfElse() { 36 36 debugger; 37 if (tru e)38 a(); 39 else 40 a(); 41 if (false )37 if (truthy) 38 a(); 39 else 40 a(); 41 if (falsey) 42 42 a(); 43 43 else … … 47 47 function entryIfElseChain() { 48 48 debugger; 49 if (false )50 a(); 51 else if (tru e)52 a(); 53 else 54 a(); 55 56 if (false )57 a(); 58 else if (false )49 if (falsey) 50 a(); 51 else if (truthy) 52 a(); 53 else 54 a(); 55 56 if (falsey) 57 a(); 58 else if (falsey) 59 59 a(); 60 60 else … … 69 69 70 70 function entryTernary() { 71 let t = () => tru e;72 let f = () => false ;71 let t = () => truthy; 72 let f = () => falsey; 73 73 debugger; 74 74 let x = t() ? a() : b(); 75 75 let y = f() ? a() : b(); 76 } 77 78 function entryIfConstantBranch() { 79 debugger; 80 if (true) 81 a(); 82 if (false) 83 a(); 84 if (0) 85 a(); 86 if (null) 87 a(); 88 } 89 90 function entryIfWithLogicalOperation() { 91 debugger; 92 if (true && a() && a()) 93 b(); 94 } 95 96 function entryIfWithBinaryOperation() { 97 let i = a(); 98 debugger; 99 if (i < 2) 100 b(); 101 } 102 103 function entryIfWithNotOperation() { 104 debugger; 105 if (!false) 106 a(); 107 if (!!true) 108 a(); 76 109 } 77 110 … … 198 231 }); 199 232 233 addSteppingTestCase({ 234 name: "Debugger.stepping.ConstantBranch", 235 description: "Should pause for constant branches.", 236 expression: "setTimeout(entryIfConstantBranch)", 237 steps: [ 238 "over", 239 "over", // (true) 240 "over", // a() 241 "over", // (false) 242 "over", // (0) 243 "over", // (null) 244 "resume", 245 ] 246 }); 247 248 addSteppingTestCase({ 249 name: "Debugger.stepping.IfWithLogicalOperation", 250 description: "Should always pause for a condition with logical operations.", 251 expression: "setTimeout(entryIfWithLogicalOperation)", 252 steps: [ 253 "over", 254 "in", // into a() 255 "out", // out of a() - before a() 256 "in", // into a() 257 "out", // out of a() - before b() 258 "over", // b() - leaving entry 259 "resume", 260 ] 261 }); 262 263 addSteppingTestCase({ 264 name: "Debugger.stepping.IfWithBinaryOperation", 265 description: "Should always pause for a condition with logical operations.", 266 expression: "setTimeout(entryIfWithBinaryOperation)", 267 steps: [ 268 "over", 269 "in", // i < 2 [true] 270 "over", // over b() - leaving entry 271 "resume", 272 ] 273 }); 274 275 addSteppingTestCase({ 276 name: "Debugger.stepping.IfWithNotOperation", 277 description: "Should always pause for a condition that is a not operation.", 278 expression: "setTimeout(entryIfWithNotOperation)", 279 steps: [ 280 "over", 281 "in", // !false 282 "over", // a() 283 "in", // !!truth 284 "over", // a() - leaving entry 285 "resume", 286 ] 287 }); 288 200 289 loadMainPageContent().then(() => { 201 290 suite.runTestCasesAndFinish(); -
trunk/LayoutTests/inspector/debugger/stepping/stepping-loops-expected.txt
r206654 r207228 149 149 -- Running test case: Debugger.stepping.TraditionalForStepOver 150 150 EXPRESSION: setTimeout(entryTraditionalFor) 151 STEPS: over, over, over, over, over, over, over, over, resume151 STEPS: over, over, over, over, over, over, over, over, over, resume 152 152 PAUSED (debugger-statement) 153 153 PAUSE AT entryTraditionalFor:27:5 … … 166 166 26 debugger; 167 167 -> 27 for (|let i = 0; i < 2; ++i) 168 28 a(); 169 29 } 170 30 171 172 ACTION: step-over 173 PAUSE AT entryTraditionalFor:28:21 174 24 175 25 function entryTraditionalFor() { 176 26 debugger; 177 -> 27 for (let i = 0; |i < 2; ++i) 168 178 28 a(); 169 179 29 } … … 450 460 -- Running test case: Debugger.stepping.ForIn 451 461 EXPRESSION: setTimeout(entryForIn) 452 STEPS: over, over, over, over, over, over, resume462 STEPS: over, over, over, over, over, over, over, resume 453 463 PAUSED (debugger-statement) 454 464 PAUSE AT entryForIn:41:5 … … 472 482 473 483 ACTION: step-over 484 PAUSE AT entryForIn:42:10 485 38 function entryForIn() { 486 39 let o = {key1: 1, key2: 2}; 487 40 debugger; 488 -> 41 for (|let property in o) 489 42 a(); 490 43 } 491 44 492 493 ACTION: step-over 474 494 PAUSE AT entryForIn:43:9 475 495 39 let o = {key1: 1, key2: 2}; … … 482 502 483 503 ACTION: step-over 484 PAUSE AT entryForIn:42: 26504 PAUSE AT entryForIn:42:10 485 505 38 function entryForIn() { 486 506 39 let o = {key1: 1, key2: 2}; 487 507 40 debugger; 488 -> 41 for ( let property in |o)508 -> 41 for (|let property in o) 489 509 42 a(); 490 510 43 } … … 502 522 503 523 ACTION: step-over 504 PAUSE AT entryForIn:42: 26524 PAUSE AT entryForIn:42:10 505 525 38 function entryForIn() { 506 526 39 let o = {key1: 1, key2: 2}; 507 527 40 debugger; 508 -> 41 for ( let property in |o)528 -> 41 for (|let property in o) 509 529 42 a(); 510 530 43 } … … 527 547 -- Running test case: Debugger.stepping.ForIn 528 548 EXPRESSION: setTimeout(entryForOf) 529 STEPS: over, over, over, over, over, over, resume549 STEPS: over, over, over, over, over, over, over, resume 530 550 PAUSED (debugger-statement) 531 551 PAUSE AT entryForOf:48:5 … … 549 569 550 570 ACTION: step-over 571 PAUSE AT entryForOf:49:10 572 45 function entryForOf() { 573 46 let arr = [1, 2]; 574 47 debugger; 575 -> 48 for (|let value of arr) 576 49 a(); 577 50 } 578 51 579 580 ACTION: step-over 551 581 PAUSE AT entryForOf:50:9 552 582 46 let arr = [1, 2]; … … 559 589 560 590 ACTION: step-over 561 PAUSE AT entryForOf:49: 23591 PAUSE AT entryForOf:49:10 562 592 45 function entryForOf() { 563 593 46 let arr = [1, 2]; 564 594 47 debugger; 565 -> 48 for ( let value of |arr)595 -> 48 for (|let value of arr) 566 596 49 a(); 567 597 50 } … … 579 609 580 610 ACTION: step-over 581 PAUSE AT entryForOf:49: 23611 PAUSE AT entryForOf:49:10 582 612 45 function entryForOf() { 583 613 46 let arr = [1, 2]; 584 614 47 debugger; 585 -> 48 for ( let value of |arr)615 -> 48 for (|let value of arr) 586 616 49 a(); 587 617 50 } … … 611 641 53 let i = 0; 612 642 -> 54 |debugger; 613 55 while (tru e) {643 55 while (truthy) { 614 644 56 ++i; 615 645 57 if (i === 1) … … 620 650 53 let i = 0; 621 651 54 debugger; 622 -> 55 while (|tru e) {652 -> 55 while (|truthy) { 623 653 56 ++i; 624 654 57 if (i === 1) … … 629 659 53 let i = 0; 630 660 54 debugger; 631 55 while (tru e) {661 55 while (truthy) { 632 662 -> 56 |++i; 633 663 57 if (i === 1) … … 638 668 PAUSE AT entryWhileBreakContinue:58:13 639 669 54 debugger; 640 55 while (tru e) {670 55 while (truthy) { 641 671 56 ++i; 642 672 -> 57 if (|i === 1) … … 647 677 ACTION: step-over 648 678 PAUSE AT entryWhileBreakContinue:59:13 649 55 while (tru e) {679 55 while (truthy) { 650 680 56 ++i; 651 681 57 if (i === 1) … … 660 690 53 let i = 0; 661 691 54 debugger; 662 -> 55 while (|tru e) {692 -> 55 while (|truthy) { 663 693 56 ++i; 664 694 57 if (i === 1) … … 669 699 53 let i = 0; 670 700 54 debugger; 671 55 while (tru e) {701 55 while (truthy) { 672 702 -> 56 |++i; 673 703 57 if (i === 1) … … 678 708 PAUSE AT entryWhileBreakContinue:58:13 679 709 54 debugger; 680 55 while (tru e) {710 55 while (truthy) { 681 711 56 ++i; 682 712 -> 57 if (|i === 1) -
trunk/LayoutTests/inspector/debugger/stepping/stepping-loops.html
r206652 r207228 5 5 <script src="../resources/log-pause-location.js"></script> 6 6 <script> 7 function a() { 8 return 1; 9 } 7 var truthy = true; 8 function a() { return 1; } 9 10 10 11 11 function entryWhile() { … … 54 54 let i = 0; 55 55 debugger; 56 while (tru e) {56 while (truthy) { 57 57 ++i; 58 58 if (i === 1) … … 118 118 steps: [ 119 119 "over", 120 "over", // complete: let i = 0; i < 2 120 "over", // complete: let i = 0 121 "over", // complete: i < 2 121 122 "over", // complete: a() 122 123 "over", // complete: ++i … … 170 171 steps: [ 171 172 "over", 173 "over", // complete: (o) 172 174 "over", // complete: let property in o [key1] 173 175 "over", // complete: a() … … 185 187 steps: [ 186 188 "over", 189 "over", // complete (arr) 187 190 "over", // complete: let value of arr [1] 188 191 "over", // complete: a() -
trunk/Source/JavaScriptCore/ChangeLog
r207226 r207228 1 2016-10-12 Joseph Pecoraro <pecoraro@apple.com> 2 3 Emit DebugHooks uniformly with pause locations instead of having separate pause locations and op_debug emits 4 https://bugs.webkit.org/show_bug.cgi?id=162809 5 6 Reviewed by Geoffrey Garen. 7 8 Change how BytecodeGeneration emits debug hooks to be more consistent. 9 Previously most nodes individually generated their own debug hook 10 and we asserted that it matched a breakpoint location identified 11 by the parser. This could get out of sync, or nodes could forget to 12 emit debug hooks expected by the parser. 13 14 With this change, we always check and emit a debug hook for any 15 node. The default behavior is for BytecodeGenerator::emitNode 16 to emit the debug hook when emitting the node itself. This covers 17 the majority of cases (statements). 18 19 There are a few exceptions where we continue to need to customize 20 emitting debug hooks: 21 22 1. Nodes with emitBytecodeInConditionContext 23 - non-Expression nodes customize how they emit their children 24 - constants conditions may emit nothing, but we had recorded a breakpoint location so emit a debug hook 25 - always emit one debug hook in case we recorded a breakpoint location, but avoid emitting multiple 26 in nodes which may call up to the ExpressionNode::emitBytecodeInConditionContext base impl. 27 2. Specialized Debug Hooks 28 - such as hooks for Program start/end, debugger statements, etc. 29 3. Debug Hooks in for..of / for..in that don't correspond to re-emitting nodes 30 - such as pausing on the assignment expression inside these loops 31 32 The majority of nodes no longer have custom emits. 33 34 * bytecompiler/BytecodeGenerator.h: 35 (JSC::BytecodeGenerator::emitNodeInTailPosition): 36 (JSC::BytecodeGenerator::emitNodeInConditionContext): 37 * bytecompiler/BytecodeGenerator.cpp: 38 (JSC::BytecodeGenerator::emitDebugHook): 39 (JSC::BytecodeGenerator::emitEnumeration): 40 By default, when emitting a node check if we should also emit an op_debug for it. 41 This default DebugHook is WillExecuteStatement, which is a normal pause point. 42 43 * bytecompiler/NodesCodegen.cpp: 44 (JSC::ConstantNode::emitBytecodeInConditionContext): 45 (JSC::LogicalNotNode::emitBytecodeInConditionContext): 46 (JSC::BinaryOpNode::emitBytecodeInConditionContext): 47 (JSC::LogicalOpNode::emitBytecodeInConditionContext): 48 The parser would have generated a pause location for these conditions 49 no matter what constant folding and re-writing these nodes may perform. 50 So, when emitting these nodes in condition context check if they need 51 emit their own debug hook. 52 53 (JSC::EmptyStatementNode::emitBytecode): 54 (JSC::ExprStatementNode::emitBytecode): 55 (JSC::DeclarationStatement::emitBytecode): 56 (JSC::IfElseNode::emitBytecode): 57 (JSC::DoWhileNode::emitBytecode): 58 (JSC::WhileNode::emitBytecode): 59 (JSC::ForNode::emitBytecode): 60 (JSC::ContinueNode::emitBytecode): 61 (JSC::BreakNode::emitBytecode): 62 (JSC::ReturnNode::emitBytecode): 63 (JSC::WithNode::emitBytecode): 64 (JSC::SwitchNode::emitBytecode): 65 (JSC::ThrowNode::emitBytecode): 66 No longer need to custom emit debug hooks. The default emitNode will handle these. 67 68 (JSC::ForInNode::emitBytecode): 69 Include extra debug hooks the user expects to return back to the assignment 70 expression in the loop header before starting the body again. The same is done 71 for for..of with emitEnumeration. 72 73 * parser/ASTBuilder.h: 74 (JSC::ASTBuilder::createExportDefaultDeclaration): 75 (JSC::ASTBuilder::createExportLocalDeclaration): 76 These are no longer needed to fake-satisfy assertions. We never wanted to 77 emit debug hooks for these inner statements because the export statement 78 will already have the debug hooks. 79 80 (JSC::ASTBuilder::createForInLoop): 81 (JSC::ASTBuilder::createForOfLoop): 82 Include the correct location where the declaration starts. 83 84 (JSC::ASTBuilder::breakpointLocation): 85 Simplify to a general implementation for Node. 86 87 * parser/SyntaxChecker.h: 88 (JSC::SyntaxChecker::createForInLoop): 89 (JSC::SyntaxChecker::createForOfLoop): 90 Ignore the new extra parameter. 91 92 * parser/Nodes.h: 93 (JSC::Node::needsDebugHook): 94 (JSC::Node::setNeedsDebugHook): 95 (JSC::ExpressionNode::needsDebugHook): Deleted. 96 (JSC::ExpressionNode::setNeedsDebugHook): Deleted. 97 (JSC::StatementNode::isEmptyStatement): Deleted. 98 (JSC::StatementNode::needsDebugHook): Deleted. 99 (JSC::StatementNode::setNeedsDebugHook): Deleted. 100 Move debug hook logic into the base Node class. 101 102 (JSC::StatementNode::isDebuggerStatement): 103 Provide a way to distinguish a debugger statement. 104 105 * parser/Parser.cpp: 106 (JSC::Parser<LexerType>::parseForStatement): 107 Provide the location before the declaration starts. 108 1 109 2016-10-12 Mark Lam <mark.lam@apple.com> 2 110 -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
r207023 r207228 3505 3505 void BytecodeGenerator::emitDebugHook(StatementNode* statement) 3506 3506 { 3507 RELEASE_ASSERT(statement->needsDebugHook()); 3507 // DebuggerStatementNode will output its own special debug hook. 3508 if (statement->isDebuggerStatement()) 3509 return; 3510 3508 3511 emitDebugHook(WillExecuteStatement, statement->position()); 3509 3512 } 3510 3513 3511 void BytecodeGenerator::emitDebugHook(ExpressionNode* expr, DebugHookType debugHookType) 3512 { 3513 RELEASE_ASSERT(expr->needsDebugHook()); 3514 emitDebugHook(debugHookType, expr->position()); 3514 void BytecodeGenerator::emitDebugHook(ExpressionNode* expr) 3515 { 3516 emitDebugHook(WillExecuteStatement, expr->position()); 3515 3517 } 3516 3518 … … 4203 4205 RELEASE_ASSERT(forLoopNode->isForOfNode()); 4204 4206 prepareLexicalScopeForNextForLoopIteration(forLoopNode, forLoopSymbolTable); 4205 emitDebugHook(forLoopNode-> expr(), WillExecuteStatement);4207 emitDebugHook(forLoopNode->lexpr()); 4206 4208 } 4207 4209 -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
r206870 r207228 387 387 return; 388 388 } 389 if (UNLIKELY(n->needsDebugHook())) 390 emitDebugHook(n); 389 391 n->emitBytecode(*this, dst); 390 392 } … … 412 414 if (UNLIKELY(!m_vm->isSafeToRecurse())) 413 415 return emitThrowExpressionTooDeepException(); 416 if (UNLIKELY(n->needsDebugHook())) 417 emitDebugHook(n); 414 418 return n->emitBytecode(*this, dst); 415 419 } … … 431 435 return; 432 436 } 433 434 437 n->emitBytecodeInConditionContext(*this, trueTarget, falseTarget, fallThroughMode); 435 438 } … … 685 688 void emitDebugHook(DebugHookType, unsigned line, unsigned charOffset, unsigned lineStart); 686 689 void emitDebugHook(StatementNode*); 687 void emitDebugHook(ExpressionNode* , DebugHookType);690 void emitDebugHook(ExpressionNode*); 688 691 void emitWillLeaveCallFrameDebugHook(); 689 692 -
trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
r206870 r207228 95 95 { 96 96 TriState value = jsValue(generator).pureToBoolean(); 97 98 if (UNLIKELY(needsDebugHook())) { 99 if (value != MixedTriState) 100 generator.emitDebugHook(this); 101 } 102 97 103 if (value == MixedTriState) 98 104 ExpressionNode::emitBytecodeInConditionContext(generator, trueTarget, falseTarget, fallThroughMode); … … 1670 1676 void LogicalNotNode::emitBytecodeInConditionContext(BytecodeGenerator& generator, Label* trueTarget, Label* falseTarget, FallThroughMode fallThroughMode) 1671 1677 { 1672 // reverse the true and false targets 1678 if (UNLIKELY(needsDebugHook())) 1679 generator.emitDebugHook(this); 1680 1681 // Reverse the true and false targets. 1673 1682 generator.emitNodeInConditionContext(expr(), falseTarget, trueTarget, invert(fallThroughMode)); 1674 1683 } … … 1800 1809 tryFoldToBranch(generator, branchCondition, branchExpression); 1801 1810 1811 if (UNLIKELY(needsDebugHook())) { 1812 if (branchCondition != MixedTriState) 1813 generator.emitDebugHook(this); 1814 } 1815 1802 1816 if (branchCondition == MixedTriState) 1803 1817 ExpressionNode::emitBytecodeInConditionContext(generator, trueTarget, falseTarget, fallThroughMode); … … 2001 2015 void LogicalOpNode::emitBytecodeInConditionContext(BytecodeGenerator& generator, Label* trueTarget, Label* falseTarget, FallThroughMode fallThroughMode) 2002 2016 { 2017 if (UNLIKELY(needsDebugHook())) 2018 generator.emitDebugHook(this); 2019 2003 2020 RefPtr<Label> afterExpr1 = generator.newLabel(); 2004 2021 if (m_operator == OpLogicalAnd) … … 2377 2394 // ------------------------------ EmptyStatementNode --------------------------- 2378 2395 2379 void EmptyStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)2380 { 2381 generator.emitDebugHook(this);2396 void EmptyStatementNode::emitBytecode(BytecodeGenerator&, RegisterID*) 2397 { 2398 RELEASE_ASSERT(needsDebugHook()); 2382 2399 } 2383 2400 … … 2394 2411 { 2395 2412 ASSERT(m_expr); 2396 generator.emitDebugHook(this);2397 2413 generator.emitNode(dst, m_expr); 2398 2414 } … … 2403 2419 { 2404 2420 ASSERT(m_expr); 2405 generator.emitDebugHook(this);2406 2421 generator.emitNode(m_expr); 2407 2422 } … … 2491 2506 void IfElseNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 2492 2507 { 2493 generator.emitDebugHook(m_condition, WillExecuteStatement);2494 2495 2508 RefPtr<Label> beforeThen = generator.newLabel(); 2496 2509 RefPtr<Label> beforeElse = generator.newLabel(); … … 2537 2550 2538 2551 generator.emitLabel(scope->continueTarget()); 2539 generator.emitDebugHook(m_expr, WillExecuteStatement);2540 2552 generator.emitNodeInConditionContext(m_expr, topOfLoop.get(), scope->breakTarget(), FallThroughMeansFalse); 2541 2553 … … 2550 2562 RefPtr<Label> topOfLoop = generator.newLabel(); 2551 2563 2552 generator.emitDebugHook(m_expr, WillExecuteStatement);2553 2564 generator.emitNodeInConditionContext(m_expr, topOfLoop.get(), scope->breakTarget(), FallThroughMeansTrue); 2554 2565 … … 2560 2571 2561 2572 generator.emitLabel(scope->continueTarget()); 2562 generator.emitDebugHook(m_expr, WillExecuteStatement);2563 2573 2564 2574 generator.emitNodeInConditionContext(m_expr, topOfLoop.get(), scope->breakTarget(), FallThroughMeansFalse); … … 2578 2588 generator.pushLexicalScope(this, BytecodeGenerator::TDZCheckOptimization::Optimize, BytecodeGenerator::NestedScopeType::IsNested, &forLoopSymbolTable); 2579 2589 2580 if (m_expr1 || m_expr2) { 2581 ExpressionNode* firstExpr = m_expr1 ? m_expr1 : m_expr2; 2582 generator.emitDebugHook(firstExpr, WillExecuteStatement); 2583 } 2584 2585 if (m_expr1) { 2586 generator.emitDebugHook(m_expr1, WillExecuteExpression); 2590 if (m_expr1) 2587 2591 generator.emitNode(generator.ignoredResult(), m_expr1); 2588 }2589 2592 2590 2593 RefPtr<Label> topOfLoop = generator.newLabel(); 2591 if (m_expr2) { 2592 generator.emitDebugHook(m_expr2, WillExecuteExpression); 2594 if (m_expr2) 2593 2595 generator.emitNodeInConditionContext(m_expr2, topOfLoop.get(), scope->breakTarget(), FallThroughMeansTrue); 2594 }2595 2596 2596 2597 generator.emitLabel(topOfLoop.get()); … … 2602 2603 generator.emitLabel(scope->continueTarget()); 2603 2604 generator.prepareLexicalScopeForNextForLoopIteration(this, forLoopSymbolTable); 2604 if (m_expr3) { 2605 generator.emitDebugHook(m_expr3, WillExecuteStatement); 2605 if (m_expr3) 2606 2606 generator.emitNode(generator.ignoredResult(), m_expr3); 2607 } 2608 2609 if (m_expr2) { 2610 generator.emitDebugHook(m_expr2, WillExecuteStatement); 2607 2608 if (m_expr2) 2611 2609 generator.emitNodeInConditionContext(m_expr2, topOfLoop.get(), scope->breakTarget(), FallThroughMeansFalse); 2612 }else2610 else 2613 2611 generator.emitJump(topOfLoop.get()); 2614 2612 … … 2739 2737 generator.pushLexicalScope(this, BytecodeGenerator::TDZCheckOptimization::Optimize, BytecodeGenerator::NestedScopeType::IsNested, &forLoopSymbolTable); 2740 2738 2741 generator.emitDebugHook(m_expr, WillExecuteStatement);2742 2743 2739 if (m_lexpr->isAssignResolveNode()) 2744 2740 generator.emitNode(generator.ignoredResult(), m_lexpr); … … 2751 2747 RefPtr<RegisterID> local = this->tryGetBoundLocal(generator); 2752 2748 RefPtr<RegisterID> enumeratorIndex; 2749 2750 // Pause at the assignment expression for each for..in iteration. 2751 generator.emitDebugHook(m_lexpr); 2753 2752 2754 2753 int profilerStartOffset = m_statement->startOffset(); … … 2789 2788 generator.prepareLexicalScopeForNextForLoopIteration(this, forLoopSymbolTable); 2790 2789 generator.emitInc(i.get()); 2791 generator.emitDebugHook(m_ expr, WillExecuteStatement);2790 generator.emitDebugHook(m_lexpr); // Pause at the assignment expression for each for..in iteration. 2792 2791 generator.emitJump(loopStart.get()); 2793 2792 … … 2829 2828 generator.emitInc(enumeratorIndex.get()); 2830 2829 generator.emitEnumeratorStructurePropertyName(propertyName.get(), enumerator.get(), enumeratorIndex.get()); 2831 generator.emitDebugHook(m_ expr, WillExecuteStatement);2830 generator.emitDebugHook(m_lexpr); // Pause at the assignment expression for each for..in iteration. 2832 2831 generator.emitJump(loopStart.get()); 2833 2832 … … 2866 2865 generator.emitInc(enumeratorIndex.get()); 2867 2866 generator.emitEnumeratorGenericPropertyName(propertyName.get(), enumerator.get(), enumeratorIndex.get()); 2868 generator.emitDebugHook(m_ expr, WillExecuteStatement);2867 generator.emitDebugHook(m_lexpr); // Pause at the assignment expression for each for..in iteration. 2869 2868 generator.emitJump(loopStart.get()); 2870 2869 … … 2963 2962 void ContinueNode::emitBytecode(BytecodeGenerator& generator, RegisterID*) 2964 2963 { 2965 generator.emitDebugHook(this);2966 2967 2964 LabelScopePtr scope = generator.continueTarget(m_ident); 2968 2965 ASSERT(scope); … … 2992 2989 void BreakNode::emitBytecode(BytecodeGenerator& generator, RegisterID*) 2993 2990 { 2994 generator.emitDebugHook(this);2995 2996 2991 LabelScopePtr scope = generator.breakTarget(m_ident); 2997 2992 ASSERT(scope); … … 3007 3002 void ReturnNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 3008 3003 { 3009 generator.emitDebugHook(this);3010 3011 3004 ASSERT(generator.codeType() == FunctionCode); 3012 3005 … … 3035 3028 void WithNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 3036 3029 { 3037 generator.emitDebugHook(m_expr, WillExecuteStatement);3038 3039 3030 RefPtr<RegisterID> scope = generator.emitNode(m_expr); 3040 3031 generator.emitExpressionInfo(m_divot, m_divot - m_expressionLength, m_divot); … … 3210 3201 void SwitchNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 3211 3202 { 3212 generator.emitDebugHook(m_expr, WillExecuteStatement);3213 3214 3203 LabelScopePtr scope = generator.newLabelScope(LabelScope::Switch); 3215 3204 … … 3240 3229 void ThrowNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 3241 3230 { 3242 generator.emitDebugHook(this);3243 3244 3231 if (dst == generator.ignoredResult()) 3245 3232 dst = 0; -
trunk/Source/JavaScriptCore/parser/ASTBuilder.h
r206671 r207228 560 560 } 561 561 562 StatementNode* createForInLoop(const JSTokenLocation& location, ExpressionNode* lhs, ExpressionNode* iter, StatementNode* statements, const JST extPosition& eStart, const JSTextPosition& eDivot, const JSTextPosition& eEnd, int start, int end, VariableEnvironment& lexicalVariables)562 StatementNode* createForInLoop(const JSTokenLocation& location, ExpressionNode* lhs, ExpressionNode* iter, StatementNode* statements, const JSTokenLocation&, const JSTextPosition& eStart, const JSTextPosition& eDivot, const JSTextPosition& eEnd, int start, int end, VariableEnvironment& lexicalVariables) 563 563 { 564 564 ForInNode* result = new (m_parserArena) ForInNode(location, lhs, iter, statements, lexicalVariables); … … 568 568 } 569 569 570 StatementNode* createForInLoop(const JSTokenLocation& location, DestructuringPatternNode* pattern, ExpressionNode* iter, StatementNode* statements, const JST extPosition& eStart, const JSTextPosition& eDivot, const JSTextPosition& eEnd, int start, int end, VariableEnvironment& lexicalVariables)571 { 572 auto lexpr = new (m_parserArena) DestructuringAssignmentNode( location, pattern, 0);573 return createForInLoop(location, lexpr, iter, statements, eStart, eDivot, eEnd, start, end, lexicalVariables);574 } 575 576 StatementNode* createForOfLoop(const JSTokenLocation& location, ExpressionNode* lhs, ExpressionNode* iter, StatementNode* statements, const JST extPosition& eStart, const JSTextPosition& eDivot, const JSTextPosition& eEnd, int start, int end, VariableEnvironment& lexicalVariables)570 StatementNode* createForInLoop(const JSTokenLocation& location, DestructuringPatternNode* pattern, ExpressionNode* iter, StatementNode* statements, const JSTokenLocation& declLocation, const JSTextPosition& eStart, const JSTextPosition& eDivot, const JSTextPosition& eEnd, int start, int end, VariableEnvironment& lexicalVariables) 571 { 572 auto lexpr = new (m_parserArena) DestructuringAssignmentNode(declLocation, pattern, nullptr); 573 return createForInLoop(location, lexpr, iter, statements, declLocation, eStart, eDivot, eEnd, start, end, lexicalVariables); 574 } 575 576 StatementNode* createForOfLoop(const JSTokenLocation& location, ExpressionNode* lhs, ExpressionNode* iter, StatementNode* statements, const JSTokenLocation&, const JSTextPosition& eStart, const JSTextPosition& eDivot, const JSTextPosition& eEnd, int start, int end, VariableEnvironment& lexicalVariables) 577 577 { 578 578 ForOfNode* result = new (m_parserArena) ForOfNode(location, lhs, iter, statements, lexicalVariables); … … 582 582 } 583 583 584 StatementNode* createForOfLoop(const JSTokenLocation& location, DestructuringPatternNode* pattern, ExpressionNode* iter, StatementNode* statements, const JST extPosition& eStart, const JSTextPosition& eDivot, const JSTextPosition& eEnd, int start, int end, VariableEnvironment& lexicalVariables)585 { 586 auto lexpr = new (m_parserArena) DestructuringAssignmentNode( location, pattern, 0);587 return createForOfLoop(location, lexpr, iter, statements, eStart, eDivot, eEnd, start, end, lexicalVariables);584 StatementNode* createForOfLoop(const JSTokenLocation& location, DestructuringPatternNode* pattern, ExpressionNode* iter, StatementNode* statements, const JSTokenLocation& declLocation, const JSTextPosition& eStart, const JSTextPosition& eDivot, const JSTextPosition& eEnd, int start, int end, VariableEnvironment& lexicalVariables) 585 { 586 auto lexpr = new (m_parserArena) DestructuringAssignmentNode(declLocation, pattern, nullptr); 587 return createForOfLoop(location, lexpr, iter, statements, declLocation, eStart, eDivot, eEnd, start, end, lexicalVariables); 588 588 } 589 589 … … 753 753 StatementNode* createExportDefaultDeclaration(const JSTokenLocation& location, StatementNode* declaration, const Identifier& localName) 754 754 { 755 // We need to mark the inner statement as needing a debug hook (so that when the statement is generated we don't756 // assert when generating an op_debug for it) without recording a breakpoint location because the export statement757 // itself will get the breakpoint location. This will be eliminated by:758 // <https://webkit.org/b/162809> Emit DebugHooks uniformly with pause locations instead of having separate pause locations and op_debug emits759 declaration->setNeedsDebugHook();760 755 return new (m_parserArena) ExportDefaultDeclarationNode(location, declaration, localName); 761 756 } … … 763 758 StatementNode* createExportLocalDeclaration(const JSTokenLocation& location, StatementNode* declaration) 764 759 { 765 // We need to mark the inner statement as needing a debug hook (so that when the statement is generated we don't766 // assert when generating an op_debug for it) without recording a breakpoint location because the export statement767 // itself will get the breakpoint location. This will be eliminated by:768 // <https://webkit.org/b/162809> Emit DebugHooks uniformly with pause locations instead of having separate pause locations and op_debug emits769 declaration->setNeedsDebugHook();770 760 return new (m_parserArena) ExportLocalDeclarationNode(location, declaration); 771 761 } … … 984 974 } 985 975 986 JSTextPosition breakpointLocation(StatementNode* statement) 987 { 988 statement->setNeedsDebugHook(); 989 return statement->position(); 990 } 991 992 JSTextPosition breakpointLocation(ExpressionNode* expr) 993 { 994 expr->setNeedsDebugHook(); 995 return expr->position(); 976 JSTextPosition breakpointLocation(Node* node) 977 { 978 node->setNeedsDebugHook(); 979 return node->position(); 996 980 } 997 981 -
trunk/Source/JavaScriptCore/parser/Nodes.h
r206653 r207228 146 146 void setStartOffset(int offset) { m_position.offset = offset; } 147 147 148 bool needsDebugHook() const { return m_needsDebugHook; } 149 void setNeedsDebugHook() { m_needsDebugHook = true; } 150 148 151 protected: 149 152 JSTextPosition m_position; 150 153 int m_endOffset; 154 bool m_needsDebugHook { false }; 151 155 }; 152 156 … … 192 196 ResultType resultDescriptor() const { return m_resultType; } 193 197 194 bool needsDebugHook() { return m_needsDebugHook; }195 void setNeedsDebugHook() { m_needsDebugHook = true; }196 197 198 private: 198 199 ResultType m_resultType; 199 bool m_needsDebugHook { false };200 200 }; 201 201 … … 214 214 215 215 virtual bool isEmptyStatement() const { return false; } 216 virtual bool isDebuggerStatement() const { return false; } 216 217 virtual bool isFunctionNode() const { return false; } 217 218 virtual bool isReturnNode() const { return false; } … … 225 226 virtual bool isForOfNode() const { return false; } 226 227 227 bool needsDebugHook() { return m_needsDebugHook; }228 void setNeedsDebugHook() { m_needsDebugHook = true; }229 230 228 protected: 231 229 StatementNode* m_next; 232 230 int m_lastLine; 233 bool m_needsDebugHook { false };234 231 }; 235 232 … … 1367 1364 public: 1368 1365 DebuggerStatementNode(const JSTokenLocation&); 1366 1367 bool isDebuggerStatement() const override { return true; } 1369 1368 1370 1369 private: … … 1474 1473 EnumerationNode(const JSTokenLocation&, ExpressionNode*, ExpressionNode*, StatementNode*, VariableEnvironment&); 1475 1474 1475 ExpressionNode* lexpr() const { return m_lexpr; } 1476 1476 ExpressionNode* expr() const { return m_expr; } 1477 1477 -
trunk/Source/JavaScriptCore/parser/Parser.cpp
r206671 r207228 1187 1187 int nonLHSCount = m_parserState.nonLHSCount; 1188 1188 int declarations = 0; 1189 JSTokenLocation declLocation(tokenLocation()); 1189 1190 JSTextPosition declsStart; 1190 1191 JSTextPosition declsEnd; … … 1281 1282 TreeStatement result; 1282 1283 if (isOfEnumeration) 1283 result = context.createForOfLoop(location, forInTarget, expr, statement, decl sStart, inLocation, exprEnd, startLine, endLine, *lexicalVariables);1284 result = context.createForOfLoop(location, forInTarget, expr, statement, declLocation, declsStart, inLocation, exprEnd, startLine, endLine, *lexicalVariables); 1284 1285 else { 1285 1286 if (isVarDeclaraton && forInInitializer) 1286 result = context.createForInLoop(location, decls, expr, statement, decl sStart, inLocation, exprEnd, startLine, endLine, *lexicalVariables);1287 result = context.createForInLoop(location, decls, expr, statement, declLocation, declsStart, inLocation, exprEnd, startLine, endLine, *lexicalVariables); 1287 1288 else 1288 result = context.createForInLoop(location, forInTarget, expr, statement, decl sStart, inLocation, exprEnd, startLine, endLine, *lexicalVariables);1289 result = context.createForInLoop(location, forInTarget, expr, statement, declLocation, declsStart, inLocation, exprEnd, startLine, endLine, *lexicalVariables); 1289 1290 } 1290 1291 popLexicalScopeIfNecessary(); … … 1373 1374 ASSERT(!decls); 1374 1375 if (isOfEnumeration) 1375 result = context.createForOfLoop(location, pattern, expr, statement, decl sStart, declsEnd, exprEnd, startLine, endLine, *lexicalVariables);1376 result = context.createForOfLoop(location, pattern, expr, statement, declLocation, declsStart, declsEnd, exprEnd, startLine, endLine, *lexicalVariables); 1376 1377 else 1377 result = context.createForInLoop(location, pattern, expr, statement, decl sStart, declsEnd, exprEnd, startLine, endLine, *lexicalVariables);1378 result = context.createForInLoop(location, pattern, expr, statement, declLocation, declsStart, declsEnd, exprEnd, startLine, endLine, *lexicalVariables); 1378 1379 1379 1380 popLexicalScopeIfNecessary(); … … 1381 1382 } 1382 1383 if (isOfEnumeration) 1383 result = context.createForOfLoop(location, decls, expr, statement, decl sStart, declsEnd, exprEnd, startLine, endLine, *lexicalVariables);1384 result = context.createForOfLoop(location, decls, expr, statement, declLocation, declsStart, declsEnd, exprEnd, startLine, endLine, *lexicalVariables); 1384 1385 else 1385 result = context.createForInLoop(location, decls, expr, statement, decl sStart, declsEnd, exprEnd, startLine, endLine, *lexicalVariables);1386 result = context.createForInLoop(location, decls, expr, statement, declLocation, declsStart, declsEnd, exprEnd, startLine, endLine, *lexicalVariables); 1386 1387 popLexicalScopeIfNecessary(); 1387 1388 return result; -
trunk/Source/JavaScriptCore/parser/SyntaxChecker.h
r206653 r207228 239 239 int createIfStatement(const JSTokenLocation&, int, int, int, int, int) { return StatementResult; } 240 240 int createForLoop(const JSTokenLocation&, int, int, int, int, int, int, VariableEnvironment&) { return StatementResult; } 241 int createForInLoop(const JSTokenLocation&, int, int, int, int, int, int, int, int, VariableEnvironment&) { return StatementResult; }242 int createForOfLoop(const JSTokenLocation&, int, int, int, int, int, int, int, int, VariableEnvironment&) { return StatementResult; }241 int createForInLoop(const JSTokenLocation&, int, int, int, const JSTokenLocation&, int, int, int, int, int, VariableEnvironment&) { return StatementResult; } 242 int createForOfLoop(const JSTokenLocation&, int, int, int, const JSTokenLocation&, int, int, int, int, int, VariableEnvironment&) { return StatementResult; } 243 243 int createEmptyStatement(const JSTokenLocation&) { return StatementResult; } 244 244 int createDeclarationStatement(const JSTokenLocation&, int, int, int) { return StatementResult; } -
trunk/Source/WebInspectorUI/ChangeLog
r207227 r207228 1 2016-10-12 Joseph Pecoraro <pecoraro@apple.com> 2 3 Emit DebugHooks uniformly with pause locations instead of having separate pause locations and op_debug emits 4 https://bugs.webkit.org/show_bug.cgi?id=162809 5 6 Reviewed by Geoffrey Garen. 7 8 * UserInterface/Views/SourceCodeTextEditor.js: 9 (WebInspector.SourceCodeTextEditor.prototype.textEditorExecutionHighlightRange): 10 When pausing on the variable assignment inside for..of and for..in don't just 11 highlight "var foo" but include the right hand side "var foo in ..." or 12 "var foo of ...". 13 1 14 2016-10-12 Joseph Pecoraro <pecoraro@apple.com> 2 15 -
trunk/Source/WebInspectorUI/UserInterface/Views/SourceCodeTextEditor.js
r207227 r207228 1237 1237 // Find a node starting at this offset. 1238 1238 // Avoid highlighting the entire program if this is the start of the first statement. 1239 // Special case the assignment expression inside of a for..of and for..in to highlight a larger range. 1239 1240 for (let node of nodes) { 1240 1241 let startOffset = node.range[0]; … … 1242 1243 callback(convertRangeOffsetsToSourceCodeOffsets(node.range)); 1243 1244 return; 1245 } 1246 if (node.type === WebInspector.ScriptSyntaxTree.NodeType.ForInStatement || node.type === WebInspector.ScriptSyntaxTree.NodeType.ForOfStatement) { 1247 if (node.left.range[0] === offset) { 1248 callback(convertRangeOffsetsToSourceCodeOffsets([node.left.range[0], node.right.range[1]])); 1249 return; 1250 } 1244 1251 } 1245 1252 if (startOffset > offset)
Note: See TracChangeset
for help on using the changeset viewer.