debug-scopes.js revision 257744e915dfc84d6d07a6b2accf8402d9ffc708
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// Simple closure formed by returning an inner function referering the outer 422// functions arguments. 423BeginTest("Closure 1"); 424 425function closure_1(a) { 426 function f() { 427 debugger; 428 return a; 429 }; 430 return f; 431} 432 433listener_delegate = function(exec_state) { 434 CheckScopeChain([debug.ScopeType.Local, 435 debug.ScopeType.Closure, 436 debug.ScopeType.Global], exec_state); 437 CheckScopeContent({a:1}, 1, exec_state); 438}; 439closure_1(1)(); 440EndTest(); 441 442 443// Simple closure formed by returning an inner function referering the outer 444// functions arguments. Due to VM optimizations parts of the actual closure is 445// missing from the debugger information. 446BeginTest("Closure 2"); 447 448function closure_2(a, b) { 449 var x = a + 2; 450 var y = b + 2; 451 function f() { 452 debugger; 453 return a + x; 454 }; 455 return f; 456} 457 458listener_delegate = function(exec_state) { 459 CheckScopeChain([debug.ScopeType.Local, 460 debug.ScopeType.Closure, 461 debug.ScopeType.Global], exec_state); 462 CheckScopeContent({a:1,x:3}, 1, exec_state); 463}; 464closure_2(1, 2)(); 465EndTest(); 466 467 468// Simple closure formed by returning an inner function referering the outer 469// functions arguments. Using all arguments and locals from the outer function 470// in the inner function makes these part of the debugger information on the 471// closure. 472BeginTest("Closure 3"); 473 474function closure_3(a, b) { 475 var x = a + 2; 476 var y = b + 2; 477 function f() { 478 debugger; 479 return a + b + x + y; 480 }; 481 return f; 482} 483 484listener_delegate = function(exec_state) { 485 CheckScopeChain([debug.ScopeType.Local, 486 debug.ScopeType.Closure, 487 debug.ScopeType.Global], exec_state); 488 CheckScopeContent({a:1,b:2,x:3,y:4}, 1, exec_state); 489}; 490closure_3(1, 2)(); 491EndTest(); 492 493 494 495// Simple closure formed by returning an inner function referering the outer 496// functions arguments. Using all arguments and locals from the outer function 497// in the inner function makes these part of the debugger information on the 498// closure. Use the inner function as well... 499BeginTest("Closure 4"); 500 501function closure_4(a, b) { 502 var x = a + 2; 503 var y = b + 2; 504 function f() { 505 debugger; 506 if (f) { 507 return a + b + x + y; 508 } 509 }; 510 return f; 511} 512 513listener_delegate = function(exec_state) { 514 CheckScopeChain([debug.ScopeType.Local, 515 debug.ScopeType.Closure, 516 debug.ScopeType.Global], exec_state); 517 CheckScopeContent({a:1,b:2,x:3,y:4,f:function(){}}, 1, exec_state); 518}; 519closure_4(1, 2)(); 520EndTest(); 521 522 523 524// Simple closure formed by returning an inner function referering the outer 525// functions arguments. In the presence of eval all arguments and locals 526// (including the inner function itself) from the outer function becomes part of 527// the debugger infformation on the closure. 528BeginTest("Closure 5"); 529 530function closure_5(a, b) { 531 var x = 3; 532 var y = 4; 533 function f() { 534 eval(''); 535 debugger; 536 return 1; 537 }; 538 return f; 539} 540 541listener_delegate = function(exec_state) { 542 CheckScopeChain([debug.ScopeType.Local, 543 debug.ScopeType.Closure, 544 debug.ScopeType.Global], exec_state); 545 CheckScopeContent({a:1,b:2,x:3,y:4,f:function(){}}, 1, exec_state); 546}; 547closure_5(1, 2)(); 548EndTest(); 549 550 551// Two closures. Due to optimizations only the parts actually used are provided 552// through the debugger information. 553BeginTest("Closure 6"); 554function closure_6(a, b) { 555 function f(a, b) { 556 var x = 3; 557 var y = 4; 558 return function() { 559 var x = 3; 560 var y = 4; 561 debugger; 562 some_global = a; 563 return f; 564 }; 565 } 566 return f(a, b); 567} 568 569listener_delegate = function(exec_state) { 570 CheckScopeChain([debug.ScopeType.Local, 571 debug.ScopeType.Closure, 572 debug.ScopeType.Closure, 573 debug.ScopeType.Global], exec_state); 574 CheckScopeContent({a:1}, 1, exec_state); 575 CheckScopeContent({f:function(){}}, 2, exec_state); 576}; 577closure_6(1, 2)(); 578EndTest(); 579 580 581// Two closures. In the presence of eval all information is provided as the 582// compiler cannot determine which parts are used. 583BeginTest("Closure 7"); 584function closure_7(a, b) { 585 var x = 3; 586 var y = 4; 587 eval('var i = 5'); 588 eval('var j = 6'); 589 function f(a, b) { 590 var x = 3; 591 var y = 4; 592 eval('var i = 5'); 593 eval('var j = 6'); 594 return function() { 595 debugger; 596 some_global = a; 597 return f; 598 }; 599 } 600 return f(a, b); 601} 602 603listener_delegate = function(exec_state) { 604 CheckScopeChain([debug.ScopeType.Local, 605 debug.ScopeType.Closure, 606 debug.ScopeType.Closure, 607 debug.ScopeType.Global], exec_state); 608 CheckScopeContent({}, 0, exec_state); 609 CheckScopeContent({a:1,b:2,x:3,y:4,i:5,j:6}, 1, exec_state); 610 CheckScopeContent({a:1,b:2,x:3,y:4,i:5,j:6,f:function(){}}, 2, exec_state); 611}; 612closure_7(1, 2)(); 613EndTest(); 614 615 616// Closure that may be optimized out. 617BeginTest("Closure 8"); 618function closure_8() { 619 (function inner(x) { 620 debugger; 621 })(2); 622} 623 624listener_delegate = function(exec_state) { 625 CheckScopeChain([debug.ScopeType.Local, 626 debug.ScopeType.Global], exec_state); 627 CheckScopeContent({x: 2}, 0, exec_state); 628}; 629closure_8(); 630EndTest(); 631 632 633BeginTest("Closure 9"); 634function closure_9() { 635 eval("var y = 1;"); 636 eval("var z = 1;"); 637 (function inner(x) { 638 y++; 639 z++; 640 debugger; 641 })(2); 642} 643 644listener_delegate = function(exec_state) { 645 CheckScopeChain([debug.ScopeType.Local, 646 debug.ScopeType.Closure, 647 debug.ScopeType.Global], exec_state); 648}; 649closure_9(); 650EndTest(); 651 652 653// Test a mixture of scopes. 654BeginTest("The full monty"); 655function the_full_monty(a, b) { 656 var x = 3; 657 var y = 4; 658 eval('var i = 5'); 659 eval('var j = 6'); 660 function f(a, b) { 661 var x = 9; 662 var y = 10; 663 eval('var i = 11'); 664 eval('var j = 12'); 665 with ({j:13}){ 666 return function() { 667 var x = 14; 668 with ({a:15}) { 669 with ({b:16}) { 670 debugger; 671 some_global = a; 672 return f; 673 } 674 } 675 }; 676 } 677 } 678 return f(a, b); 679} 680 681listener_delegate = function(exec_state) { 682 CheckScopeChain([debug.ScopeType.With, 683 debug.ScopeType.With, 684 debug.ScopeType.Local, 685 debug.ScopeType.With, 686 debug.ScopeType.Closure, 687 debug.ScopeType.Closure, 688 debug.ScopeType.Global], exec_state); 689 CheckScopeContent({b:16}, 0, exec_state); 690 CheckScopeContent({a:15}, 1, exec_state); 691 CheckScopeContent({x:14}, 2, exec_state); 692 CheckScopeContent({j:13}, 3, exec_state); 693 CheckScopeContent({a:1,b:2,x:9,y:10,i:11,j:12}, 4, exec_state); 694 CheckScopeContent({a:1,b:2,x:3,y:4,i:5,j:6,f:function(){}}, 5, exec_state); 695}; 696the_full_monty(1, 2)(); 697EndTest(); 698 699 700BeginTest("Closure inside With 1"); 701function closure_in_with_1() { 702 with({x:1}) { 703 (function inner(x) { 704 debugger; 705 })(2); 706 } 707} 708 709listener_delegate = function(exec_state) { 710 CheckScopeChain([debug.ScopeType.Local, 711 debug.ScopeType.With, 712 debug.ScopeType.Closure, 713 debug.ScopeType.Global], exec_state); 714 CheckScopeContent({x: 2}, 0, exec_state); 715}; 716closure_in_with_1(); 717EndTest(); 718 719 720BeginTest("Closure inside With 2"); 721function closure_in_with_2() { 722 with({x:1}) { 723 (function inner(x) { 724 with({x:3}) { 725 debugger; 726 } 727 })(2); 728 } 729} 730 731listener_delegate = function(exec_state) { 732 CheckScopeChain([debug.ScopeType.With, 733 debug.ScopeType.Local, 734 debug.ScopeType.With, 735 debug.ScopeType.Closure, 736 debug.ScopeType.Global], exec_state); 737 CheckScopeContent({x: 3}, 0, exec_state); 738 CheckScopeContent({x: 2}, 1, exec_state); 739 CheckScopeContent({x: 1}, 2, exec_state); 740}; 741closure_in_with_2(); 742EndTest(); 743 744 745BeginTest("Closure inside With 3"); 746function createClosure(a) { 747 var b = a + 1; 748 return function closure() { 749 var c = b; 750 (function inner(x) { 751 with({x:c}) { 752 debugger; 753 } 754 })(2); 755 }; 756} 757 758function closure_in_with_3() { 759 var f = createClosure(0); 760 f(); 761} 762 763listener_delegate = function(exec_state) { 764 CheckScopeChain([debug.ScopeType.With, 765 debug.ScopeType.Local, 766 debug.ScopeType.Closure, 767 debug.ScopeType.Closure, 768 debug.ScopeType.Global], exec_state); 769} 770closure_in_with_3(); 771EndTest(); 772 773 774// Test global scope. 775BeginTest("Global"); 776listener_delegate = function(exec_state) { 777 CheckScopeChain([debug.ScopeType.Global], exec_state); 778}; 779debugger; 780EndTest(); 781 782 783BeginTest("Catch block 1"); 784function catch_block_1() { 785 try { 786 throw 'Exception'; 787 } catch (e) { 788 debugger; 789 } 790}; 791 792 793listener_delegate = function(exec_state) { 794 CheckScopeChain([debug.ScopeType.Catch, 795 debug.ScopeType.Local, 796 debug.ScopeType.Global], exec_state); 797 CheckScopeContent({e:'Exception'}, 0, exec_state); 798}; 799catch_block_1(); 800EndTest(); 801 802 803BeginTest("Catch block 2"); 804function catch_block_2() { 805 try { 806 throw 'Exception'; 807 } catch (e) { 808 with({n:10}) { 809 debugger; 810 } 811 } 812}; 813 814 815listener_delegate = function(exec_state) { 816 CheckScopeChain([debug.ScopeType.With, 817 debug.ScopeType.Catch, 818 debug.ScopeType.Local, 819 debug.ScopeType.Global], exec_state); 820 CheckScopeContent({n:10}, 0, exec_state); 821 CheckScopeContent({e:'Exception'}, 1, exec_state); 822}; 823catch_block_2(); 824EndTest(); 825 826 827BeginTest("Catch block 3"); 828function catch_block_3() { 829 // Do eval to dynamically declare a local variable so that the context's 830 // extension slot is initialized with JSContextExtensionObject. 831 eval("var y = 78;"); 832 try { 833 throw 'Exception'; 834 } catch (e) { 835 debugger; 836 } 837}; 838 839 840listener_delegate = function(exec_state) { 841 CheckScopeChain([debug.ScopeType.Catch, 842 debug.ScopeType.Local, 843 debug.ScopeType.Global], exec_state); 844 CheckScopeContent({e:'Exception'}, 0, exec_state); 845 CheckScopeContent({y:78}, 1, exec_state); 846}; 847catch_block_3(); 848EndTest(); 849 850 851BeginTest("Catch block 4"); 852function catch_block_4() { 853 // Do eval to dynamically declare a local variable so that the context's 854 // extension slot is initialized with JSContextExtensionObject. 855 eval("var y = 98;"); 856 try { 857 throw 'Exception'; 858 } catch (e) { 859 with({n:10}) { 860 debugger; 861 } 862 } 863}; 864 865listener_delegate = function(exec_state) { 866 CheckScopeChain([debug.ScopeType.With, 867 debug.ScopeType.Catch, 868 debug.ScopeType.Local, 869 debug.ScopeType.Global], exec_state); 870 CheckScopeContent({n:10}, 0, exec_state); 871 CheckScopeContent({e:'Exception'}, 1, exec_state); 872 CheckScopeContent({y:98}, 2, exec_state); 873}; 874catch_block_4(); 875EndTest(); 876 877 878assertEquals(begin_test_count, break_count, 879 'one or more tests did not enter the debugger'); 880assertEquals(begin_test_count, end_test_count, 881 'one or more tests did not have its result checked'); 882