debug-scopes.js revision 85b71799222b55eb5dd74ea26efe0c64ab655c8c
1// Copyright 2008 the V8 project authors. All rights reserved. 2// Redistribution and use in source and binary forms, with or without 3// modification, are permitted provided that the following conditions are 4// met: 5// 6// * Redistributions of source code must retain the above copyright 7// notice, this list of conditions and the following disclaimer. 8// * Redistributions in binary form must reproduce the above 9// copyright notice, this list of conditions and the following 10// disclaimer in the documentation and/or other materials provided 11// with the distribution. 12// * Neither the name of Google Inc. nor the names of its 13// contributors may be used to endorse or promote products derived 14// from this software without specific prior written permission. 15// 16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28// Flags: --expose-debug-as debug 29// The functions used for testing backtraces. They are at the top to make the 30// testing of source line/column easier. 31 32 33// Get the Debug object exposed from the debug context global object. 34Debug = debug.Debug; 35 36var test_name; 37var listener_delegate; 38var listener_called; 39var exception; 40var begin_test_count = 0; 41var end_test_count = 0; 42var break_count = 0; 43 44 45// Debug event listener which delegates. 46function listener(event, exec_state, event_data, data) { 47 try { 48 if (event == Debug.DebugEvent.Break) { 49 break_count++; 50 listener_called = true; 51 listener_delegate(exec_state); 52 } 53 } catch (e) { 54 exception = e; 55 } 56} 57 58// Add the debug event listener. 59Debug.setListener(listener); 60 61 62// Initialize for a new test. 63function BeginTest(name) { 64 test_name = name; 65 listener_delegate = null; 66 listener_called = false; 67 exception = null; 68 begin_test_count++; 69} 70 71 72// Check result of a test. 73function EndTest() { 74 assertTrue(listener_called, "listerner not called for " + test_name); 75 assertNull(exception, test_name); 76 end_test_count++; 77} 78 79 80// Check that the scope chain contains the expected types of scopes. 81function CheckScopeChain(scopes, exec_state) { 82 assertEquals(scopes.length, exec_state.frame().scopeCount()); 83 for (var i = 0; i < scopes.length; i++) { 84 var scope = exec_state.frame().scope(i); 85 assertTrue(scope.isScope()); 86 assertEquals(scopes[i], scope.scopeType()); 87 88 // Check the global object when hitting the global scope. 89 if (scopes[i] == debug.ScopeType.Global) { 90 // Objects don't have same class (one is "global", other is "Object", 91 // so just check the properties directly. 92 assertPropertiesEqual(this, scope.scopeObject().value()); 93 } 94 } 95 96 // Get the debug command processor. 97 var dcp = exec_state.debugCommandProcessor("unspecified_running_state"); 98 99 // Send a scopes request and check the result. 100 var json; 101 var request_json = '{"seq":0,"type":"request","command":"scopes"}'; 102 var response_json = dcp.processDebugJSONRequest(request_json); 103 var response = JSON.parse(response_json); 104 assertEquals(scopes.length, response.body.scopes.length); 105 for (var i = 0; i < scopes.length; i++) { 106 assertEquals(i, response.body.scopes[i].index); 107 assertEquals(scopes[i], response.body.scopes[i].type); 108 if (scopes[i] == debug.ScopeType.Local || 109 scopes[i] == debug.ScopeType.Closure) { 110 assertTrue(response.body.scopes[i].object.ref < 0); 111 } else { 112 assertTrue(response.body.scopes[i].object.ref >= 0); 113 } 114 var found = false; 115 for (var j = 0; j < response.refs.length && !found; j++) { 116 found = response.refs[j].handle == response.body.scopes[i].object.ref; 117 } 118 assertTrue(found, "Scope object " + response.body.scopes[i].object.ref + " not found"); 119 } 120} 121 122 123// Check that the content of the scope is as expected. For functions just check 124// that there is a function. 125function CheckScopeContent(content, number, exec_state) { 126 var scope = exec_state.frame().scope(number); 127 var count = 0; 128 for (var p in content) { 129 var property_mirror = scope.scopeObject().property(p); 130 assertFalse(property_mirror.isUndefined(), 'property ' + p + ' not found in scope'); 131 if (typeof(content[p]) === 'function') { 132 assertTrue(property_mirror.value().isFunction()); 133 } else { 134 assertEquals(content[p], property_mirror.value().value(), 'property ' + p + ' has unexpected value'); 135 } 136 count++; 137 } 138 139 // 'arguments' and might be exposed in the local and closure scope. Just 140 // ignore this. 141 var scope_size = scope.scopeObject().properties().length; 142 if (!scope.scopeObject().property('arguments').isUndefined()) { 143 scope_size--; 144 } 145 // Also ignore synthetic variable from catch block. 146 if (!scope.scopeObject().property('.catch-var').isUndefined()) { 147 scope_size--; 148 } 149 // Skip property with empty name. 150 if (!scope.scopeObject().property('').isUndefined()) { 151 scope_size--; 152 } 153 154 if (count != scope_size) { 155 print('Names found in scope:'); 156 var names = scope.scopeObject().propertyNames(); 157 for (var i = 0; i < names.length; i++) { 158 print(names[i]); 159 } 160 } 161 assertEquals(count, scope_size); 162 163 // Get the debug command processor. 164 var dcp = exec_state.debugCommandProcessor("unspecified_running_state"); 165 166 // Send a scope request for information on a single scope and check the 167 // result. 168 var request_json = '{"seq":0,"type":"request","command":"scope","arguments":{"number":'; 169 request_json += scope.scopeIndex(); 170 request_json += '}}'; 171 var response_json = dcp.processDebugJSONRequest(request_json); 172 var response = JSON.parse(response_json); 173 assertEquals(scope.scopeType(), response.body.type); 174 assertEquals(number, response.body.index); 175 if (scope.scopeType() == debug.ScopeType.Local || 176 scope.scopeType() == debug.ScopeType.Closure) { 177 assertTrue(response.body.object.ref < 0); 178 } else { 179 assertTrue(response.body.object.ref >= 0); 180 } 181 var found = false; 182 for (var i = 0; i < response.refs.length && !found; i++) { 183 found = response.refs[i].handle == response.body.object.ref; 184 } 185 assertTrue(found, "Scope object " + response.body.object.ref + " not found"); 186} 187 188 189// Simple empty local scope. 190BeginTest("Local 1"); 191 192function local_1() { 193 debugger; 194} 195 196listener_delegate = function(exec_state) { 197 CheckScopeChain([debug.ScopeType.Local, 198 debug.ScopeType.Global], exec_state); 199 CheckScopeContent({}, 0, exec_state); 200}; 201local_1(); 202EndTest(); 203 204 205// Local scope with a parameter. 206BeginTest("Local 2"); 207 208function local_2(a) { 209 debugger; 210} 211 212listener_delegate = function(exec_state) { 213 CheckScopeChain([debug.ScopeType.Local, 214 debug.ScopeType.Global], exec_state); 215 CheckScopeContent({a:1}, 0, exec_state); 216}; 217local_2(1); 218EndTest(); 219 220 221// Local scope with a parameter and a local variable. 222BeginTest("Local 3"); 223 224function local_3(a) { 225 var x = 3; 226 debugger; 227} 228 229listener_delegate = function(exec_state) { 230 CheckScopeChain([debug.ScopeType.Local, 231 debug.ScopeType.Global], exec_state); 232 CheckScopeContent({a:1,x:3}, 0, exec_state); 233}; 234local_3(1); 235EndTest(); 236 237 238// Local scope with parameters and local variables. 239BeginTest("Local 4"); 240 241function local_4(a, b) { 242 var x = 3; 243 var y = 4; 244 debugger; 245} 246 247listener_delegate = function(exec_state) { 248 CheckScopeChain([debug.ScopeType.Local, 249 debug.ScopeType.Global], exec_state); 250 CheckScopeContent({a:1,b:2,x:3,y:4}, 0, exec_state); 251}; 252local_4(1, 2); 253EndTest(); 254 255 256// Empty local scope with use of eval. 257BeginTest("Local 5"); 258 259function local_5() { 260 eval(''); 261 debugger; 262} 263 264listener_delegate = function(exec_state) { 265 CheckScopeChain([debug.ScopeType.Local, 266 debug.ScopeType.Global], exec_state); 267 CheckScopeContent({}, 0, exec_state); 268}; 269local_5(); 270EndTest(); 271 272 273// Local introducing local variable using eval. 274BeginTest("Local 6"); 275 276function local_6() { 277 eval('var i = 5'); 278 debugger; 279} 280 281listener_delegate = function(exec_state) { 282 CheckScopeChain([debug.ScopeType.Local, 283 debug.ScopeType.Global], exec_state); 284 CheckScopeContent({i:5}, 0, exec_state); 285}; 286local_6(); 287EndTest(); 288 289 290// Local scope with parameters, local variables and local variable introduced 291// using eval. 292BeginTest("Local 7"); 293 294function local_7(a, b) { 295 var x = 3; 296 var y = 4; 297 eval('var i = 5'); 298 eval('var j = 6'); 299 debugger; 300} 301 302listener_delegate = function(exec_state) { 303 CheckScopeChain([debug.ScopeType.Local, 304 debug.ScopeType.Global], exec_state); 305 CheckScopeContent({a:1,b:2,x:3,y:4,i:5,j:6}, 0, exec_state); 306}; 307local_7(1, 2); 308EndTest(); 309 310 311// Single empty with block. 312BeginTest("With 1"); 313 314function with_1() { 315 with({}) { 316 debugger; 317 } 318} 319 320listener_delegate = function(exec_state) { 321 CheckScopeChain([debug.ScopeType.With, 322 debug.ScopeType.Local, 323 debug.ScopeType.Global], exec_state); 324 CheckScopeContent({}, 0, exec_state); 325}; 326with_1(); 327EndTest(); 328 329 330// Nested empty with blocks. 331BeginTest("With 2"); 332 333function with_2() { 334 with({}) { 335 with({}) { 336 debugger; 337 } 338 } 339} 340 341listener_delegate = function(exec_state) { 342 CheckScopeChain([debug.ScopeType.With, 343 debug.ScopeType.With, 344 debug.ScopeType.Local, 345 debug.ScopeType.Global], exec_state); 346 CheckScopeContent({}, 0, exec_state); 347 CheckScopeContent({}, 1, exec_state); 348}; 349with_2(); 350EndTest(); 351 352 353// With block using an in-place object literal. 354BeginTest("With 3"); 355 356function with_3() { 357 with({a:1,b:2}) { 358 debugger; 359 } 360} 361 362listener_delegate = function(exec_state) { 363 CheckScopeChain([debug.ScopeType.With, 364 debug.ScopeType.Local, 365 debug.ScopeType.Global], exec_state); 366 CheckScopeContent({a:1,b:2}, 0, exec_state); 367}; 368with_3(); 369EndTest(); 370 371 372// Nested with blocks using in-place object literals. 373BeginTest("With 4"); 374 375function with_4() { 376 with({a:1,b:2}) { 377 with({a:2,b:1}) { 378 debugger; 379 } 380 } 381} 382 383listener_delegate = function(exec_state) { 384 CheckScopeChain([debug.ScopeType.With, 385 debug.ScopeType.With, 386 debug.ScopeType.Local, 387 debug.ScopeType.Global], exec_state); 388 CheckScopeContent({a:2,b:1}, 0, exec_state); 389 CheckScopeContent({a:1,b:2}, 1, exec_state); 390}; 391with_4(); 392EndTest(); 393 394 395// Nested with blocks using existing object. 396BeginTest("With 5"); 397 398var with_object = {c:3,d:4}; 399function with_5() { 400 with(with_object) { 401 with(with_object) { 402 debugger; 403 } 404 } 405} 406 407listener_delegate = function(exec_state) { 408 CheckScopeChain([debug.ScopeType.With, 409 debug.ScopeType.With, 410 debug.ScopeType.Local, 411 debug.ScopeType.Global], exec_state); 412 CheckScopeContent(with_object, 0, exec_state); 413 CheckScopeContent(with_object, 1, exec_state); 414 assertEquals(exec_state.frame().scope(0).scopeObject(), exec_state.frame().scope(1).scopeObject()); 415 assertEquals(with_object, exec_state.frame().scope(1).scopeObject().value()); 416}; 417with_5(); 418EndTest(); 419 420 421// Nested with blocks using existing object in global code. 422BeginTest("With 6"); 423listener_delegate = function(exec_state) { 424 CheckScopeChain([debug.ScopeType.With, 425 debug.ScopeType.With, 426 debug.ScopeType.Global], exec_state); 427 CheckScopeContent(with_object, 0, exec_state); 428 CheckScopeContent(with_object, 1, exec_state); 429 assertEquals(exec_state.frame().scope(0).scopeObject(), exec_state.frame().scope(1).scopeObject()); 430 assertEquals(with_object, exec_state.frame().scope(1).scopeObject().value()); 431}; 432 433var with_object = {c:3,d:4}; 434with(with_object) { 435 with(with_object) { 436 debugger; 437 } 438} 439EndTest(); 440 441 442// Simple closure formed by returning an inner function referering the outer 443// functions arguments. 444BeginTest("Closure 1"); 445 446function closure_1(a) { 447 function f() { 448 debugger; 449 return a; 450 }; 451 return f; 452} 453 454listener_delegate = function(exec_state) { 455 CheckScopeChain([debug.ScopeType.Local, 456 debug.ScopeType.Closure, 457 debug.ScopeType.Global], exec_state); 458 CheckScopeContent({a:1}, 1, exec_state); 459}; 460closure_1(1)(); 461EndTest(); 462 463 464// Simple closure formed by returning an inner function referering the outer 465// functions arguments. Due to VM optimizations parts of the actual closure is 466// missing from the debugger information. 467BeginTest("Closure 2"); 468 469function closure_2(a, b) { 470 var x = a + 2; 471 var y = b + 2; 472 function f() { 473 debugger; 474 return a + x; 475 }; 476 return f; 477} 478 479listener_delegate = function(exec_state) { 480 CheckScopeChain([debug.ScopeType.Local, 481 debug.ScopeType.Closure, 482 debug.ScopeType.Global], exec_state); 483 CheckScopeContent({a:1,x:3}, 1, exec_state); 484}; 485closure_2(1, 2)(); 486EndTest(); 487 488 489// Simple closure formed by returning an inner function referering the outer 490// functions arguments. Using all arguments and locals from the outer function 491// in the inner function makes these part of the debugger information on the 492// closure. 493BeginTest("Closure 3"); 494 495function closure_3(a, b) { 496 var x = a + 2; 497 var y = b + 2; 498 function f() { 499 debugger; 500 return a + b + x + y; 501 }; 502 return f; 503} 504 505listener_delegate = function(exec_state) { 506 CheckScopeChain([debug.ScopeType.Local, 507 debug.ScopeType.Closure, 508 debug.ScopeType.Global], exec_state); 509 CheckScopeContent({a:1,b:2,x:3,y:4}, 1, exec_state); 510}; 511closure_3(1, 2)(); 512EndTest(); 513 514 515 516// Simple closure formed by returning an inner function referering the outer 517// functions arguments. Using all arguments and locals from the outer function 518// in the inner function makes these part of the debugger information on the 519// closure. Use the inner function as well... 520BeginTest("Closure 4"); 521 522function closure_4(a, b) { 523 var x = a + 2; 524 var y = b + 2; 525 function f() { 526 debugger; 527 if (f) { 528 return a + b + x + y; 529 } 530 }; 531 return f; 532} 533 534listener_delegate = function(exec_state) { 535 CheckScopeChain([debug.ScopeType.Local, 536 debug.ScopeType.Closure, 537 debug.ScopeType.Global], exec_state); 538 CheckScopeContent({a:1,b:2,x:3,y:4,f:function(){}}, 1, exec_state); 539}; 540closure_4(1, 2)(); 541EndTest(); 542 543 544 545// Simple closure formed by returning an inner function referering the outer 546// functions arguments. In the presence of eval all arguments and locals 547// (including the inner function itself) from the outer function becomes part of 548// the debugger infformation on the closure. 549BeginTest("Closure 5"); 550 551function closure_5(a, b) { 552 var x = 3; 553 var y = 4; 554 function f() { 555 eval(''); 556 debugger; 557 return 1; 558 }; 559 return f; 560} 561 562listener_delegate = function(exec_state) { 563 CheckScopeChain([debug.ScopeType.Local, 564 debug.ScopeType.Closure, 565 debug.ScopeType.Global], exec_state); 566 CheckScopeContent({a:1,b:2,x:3,y:4,f:function(){}}, 1, exec_state); 567}; 568closure_5(1, 2)(); 569EndTest(); 570 571 572// Two closures. Due to optimizations only the parts actually used are provided 573// through the debugger information. 574BeginTest("Closure 6"); 575function closure_6(a, b) { 576 function f(a, b) { 577 var x = 3; 578 var y = 4; 579 return function() { 580 var x = 3; 581 var y = 4; 582 debugger; 583 some_global = a; 584 return f; 585 }; 586 } 587 return f(a, b); 588} 589 590listener_delegate = function(exec_state) { 591 CheckScopeChain([debug.ScopeType.Local, 592 debug.ScopeType.Closure, 593 debug.ScopeType.Closure, 594 debug.ScopeType.Global], exec_state); 595 CheckScopeContent({a:1}, 1, exec_state); 596 CheckScopeContent({f:function(){}}, 2, exec_state); 597}; 598closure_6(1, 2)(); 599EndTest(); 600 601 602// Two closures. In the presence of eval all information is provided as the 603// compiler cannot determine which parts are used. 604BeginTest("Closure 7"); 605function closure_7(a, b) { 606 var x = 3; 607 var y = 4; 608 eval('var i = 5'); 609 eval('var j = 6'); 610 function f(a, b) { 611 var x = 3; 612 var y = 4; 613 eval('var i = 5'); 614 eval('var j = 6'); 615 return function() { 616 debugger; 617 some_global = a; 618 return f; 619 }; 620 } 621 return f(a, b); 622} 623 624listener_delegate = function(exec_state) { 625 CheckScopeChain([debug.ScopeType.Local, 626 debug.ScopeType.Closure, 627 debug.ScopeType.Closure, 628 debug.ScopeType.Global], exec_state); 629 CheckScopeContent({}, 0, exec_state); 630 CheckScopeContent({a:1,b:2,x:3,y:4,i:5,j:6}, 1, exec_state); 631 CheckScopeContent({a:1,b:2,x:3,y:4,i:5,j:6,f:function(){}}, 2, exec_state); 632}; 633closure_7(1, 2)(); 634EndTest(); 635 636 637// Closure that may be optimized out. 638BeginTest("Closure 8"); 639function closure_8() { 640 (function inner(x) { 641 debugger; 642 })(2); 643} 644 645listener_delegate = function(exec_state) { 646 CheckScopeChain([debug.ScopeType.Local, 647 debug.ScopeType.Global], exec_state); 648 CheckScopeContent({x: 2}, 0, exec_state); 649}; 650closure_8(); 651EndTest(); 652 653 654BeginTest("Closure 9"); 655function closure_9() { 656 eval("var y = 1;"); 657 eval("var z = 1;"); 658 (function inner(x) { 659 y++; 660 z++; 661 debugger; 662 })(2); 663} 664 665listener_delegate = function(exec_state) { 666 CheckScopeChain([debug.ScopeType.Local, 667 debug.ScopeType.Closure, 668 debug.ScopeType.Global], exec_state); 669}; 670closure_9(); 671EndTest(); 672 673 674// Test a mixture of scopes. 675BeginTest("The full monty"); 676function the_full_monty(a, b) { 677 var x = 3; 678 var y = 4; 679 eval('var i = 5'); 680 eval('var j = 6'); 681 function f(a, b) { 682 var x = 9; 683 var y = 10; 684 eval('var i = 11'); 685 eval('var j = 12'); 686 with ({j:13}){ 687 return function() { 688 var x = 14; 689 with ({a:15}) { 690 with ({b:16}) { 691 debugger; 692 some_global = a; 693 return f; 694 } 695 } 696 }; 697 } 698 } 699 return f(a, b); 700} 701 702listener_delegate = function(exec_state) { 703 CheckScopeChain([debug.ScopeType.With, 704 debug.ScopeType.With, 705 debug.ScopeType.Local, 706 debug.ScopeType.With, 707 debug.ScopeType.Closure, 708 debug.ScopeType.Closure, 709 debug.ScopeType.Global], exec_state); 710 CheckScopeContent({b:16}, 0, exec_state); 711 CheckScopeContent({a:15}, 1, exec_state); 712 CheckScopeContent({x:14}, 2, exec_state); 713 CheckScopeContent({j:13}, 3, exec_state); 714 CheckScopeContent({a:1,b:2,x:9,y:10,i:11,j:12}, 4, exec_state); 715 CheckScopeContent({a:1,b:2,x:3,y:4,i:5,j:6,f:function(){}}, 5, exec_state); 716}; 717the_full_monty(1, 2)(); 718EndTest(); 719 720 721BeginTest("Closure inside With 1"); 722function closure_in_with_1() { 723 with({x:1}) { 724 (function inner(x) { 725 debugger; 726 })(2); 727 } 728} 729 730listener_delegate = function(exec_state) { 731 CheckScopeChain([debug.ScopeType.Local, 732 debug.ScopeType.With, 733 debug.ScopeType.Closure, 734 debug.ScopeType.Global], exec_state); 735 CheckScopeContent({x: 2}, 0, exec_state); 736}; 737closure_in_with_1(); 738EndTest(); 739 740 741BeginTest("Closure inside With 2"); 742function closure_in_with_2() { 743 with({x:1}) { 744 (function inner(x) { 745 with({x:3}) { 746 debugger; 747 } 748 })(2); 749 } 750} 751 752listener_delegate = function(exec_state) { 753 CheckScopeChain([debug.ScopeType.With, 754 debug.ScopeType.Local, 755 debug.ScopeType.With, 756 debug.ScopeType.Closure, 757 debug.ScopeType.Global], exec_state); 758 CheckScopeContent({x: 3}, 0, exec_state); 759 CheckScopeContent({x: 2}, 1, exec_state); 760 CheckScopeContent({x: 1}, 2, exec_state); 761}; 762closure_in_with_2(); 763EndTest(); 764 765 766BeginTest("Closure inside With 3"); 767function createClosure(a) { 768 var b = a + 1; 769 return function closure() { 770 var c = b; 771 (function inner(x) { 772 with({x:c}) { 773 debugger; 774 } 775 })(2); 776 }; 777} 778 779function closure_in_with_3() { 780 var f = createClosure(0); 781 f(); 782} 783 784listener_delegate = function(exec_state) { 785 CheckScopeChain([debug.ScopeType.With, 786 debug.ScopeType.Local, 787 debug.ScopeType.Closure, 788 debug.ScopeType.Closure, 789 debug.ScopeType.Global], exec_state); 790} 791closure_in_with_3(); 792EndTest(); 793 794 795BeginTest("Closure inside With 4"); 796listener_delegate = function(exec_state) { 797 CheckScopeChain([debug.ScopeType.Local, 798 debug.ScopeType.With, 799 debug.ScopeType.Global], exec_state); 800 CheckScopeContent({x: 2}, 0, exec_state); 801 CheckScopeContent({x: 1}, 1, exec_state); 802}; 803 804with({x:1}) { 805 (function(x) { 806 debugger; 807 })(2); 808} 809EndTest(); 810 811 812// Test global scope. 813BeginTest("Global"); 814listener_delegate = function(exec_state) { 815 CheckScopeChain([debug.ScopeType.Global], exec_state); 816}; 817debugger; 818EndTest(); 819 820 821BeginTest("Catch block 1"); 822function catch_block_1() { 823 try { 824 throw 'Exception'; 825 } catch (e) { 826 debugger; 827 } 828}; 829 830 831listener_delegate = function(exec_state) { 832 CheckScopeChain([debug.ScopeType.Catch, 833 debug.ScopeType.Local, 834 debug.ScopeType.Global], exec_state); 835 CheckScopeContent({e:'Exception'}, 0, exec_state); 836}; 837catch_block_1(); 838EndTest(); 839 840 841BeginTest("Catch block 2"); 842function catch_block_2() { 843 try { 844 throw 'Exception'; 845 } catch (e) { 846 with({n:10}) { 847 debugger; 848 } 849 } 850}; 851 852 853listener_delegate = function(exec_state) { 854 CheckScopeChain([debug.ScopeType.With, 855 debug.ScopeType.Catch, 856 debug.ScopeType.Local, 857 debug.ScopeType.Global], exec_state); 858 CheckScopeContent({n:10}, 0, exec_state); 859 CheckScopeContent({e:'Exception'}, 1, exec_state); 860}; 861catch_block_2(); 862EndTest(); 863 864 865BeginTest("Catch block 3"); 866function catch_block_3() { 867 // Do eval to dynamically declare a local variable so that the context's 868 // extension slot is initialized with JSContextExtensionObject. 869 eval("var y = 78;"); 870 try { 871 throw 'Exception'; 872 } catch (e) { 873 debugger; 874 } 875}; 876 877 878listener_delegate = function(exec_state) { 879 CheckScopeChain([debug.ScopeType.Catch, 880 debug.ScopeType.Local, 881 debug.ScopeType.Global], exec_state); 882 CheckScopeContent({e:'Exception'}, 0, exec_state); 883 CheckScopeContent({y:78}, 1, exec_state); 884}; 885catch_block_3(); 886EndTest(); 887 888 889BeginTest("Catch block 4"); 890function catch_block_4() { 891 // Do eval to dynamically declare a local variable so that the context's 892 // extension slot is initialized with JSContextExtensionObject. 893 eval("var y = 98;"); 894 try { 895 throw 'Exception'; 896 } catch (e) { 897 with({n:10}) { 898 debugger; 899 } 900 } 901}; 902 903listener_delegate = function(exec_state) { 904 CheckScopeChain([debug.ScopeType.With, 905 debug.ScopeType.Catch, 906 debug.ScopeType.Local, 907 debug.ScopeType.Global], exec_state); 908 CheckScopeContent({n:10}, 0, exec_state); 909 CheckScopeContent({e:'Exception'}, 1, exec_state); 910 CheckScopeContent({y:98}, 2, exec_state); 911}; 912catch_block_4(); 913EndTest(); 914 915 916// Test catch in global scope. 917BeginTest("Catch block 5"); 918listener_delegate = function(exec_state) { 919 CheckScopeChain([debug.ScopeType.Catch, 920 debug.ScopeType.Global], exec_state); 921 CheckScopeContent({e:'Exception'}, 0, exec_state); 922}; 923 924try { 925 throw 'Exception'; 926} catch (e) { 927 debugger; 928} 929 930EndTest(); 931 932 933// Closure inside catch in global code. 934BeginTest("Catch block 6"); 935listener_delegate = function(exec_state) { 936 CheckScopeChain([debug.ScopeType.Local, 937 debug.ScopeType.Catch, 938 debug.ScopeType.Global], exec_state); 939 CheckScopeContent({x: 2}, 0, exec_state); 940 CheckScopeContent({e:'Exception'}, 1, exec_state); 941}; 942 943try { 944 throw 'Exception'; 945} catch (e) { 946 (function(x) { 947 debugger; 948 })(2); 949} 950EndTest(); 951 952 953assertEquals(begin_test_count, break_count, 954 'one or more tests did not enter the debugger'); 955assertEquals(begin_test_count, end_test_count, 956 'one or more tests did not have its result checked'); 957