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 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 noew 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 assertEquals(this, scope.scopeObject().value()); 91 } 92 } 93 94 // Get the debug command processor. 95 var dcp = exec_state.debugCommandProcessor("unspecified_running_state"); 96 97 // Send a scopes request and check the result. 98 var json; 99 request_json = '{"seq":0,"type":"request","command":"scopes"}' 100 var response_json = dcp.processDebugJSONRequest(request_json); 101 var response = JSON.parse(response_json); 102 assertEquals(scopes.length, response.body.scopes.length); 103 for (var i = 0; i < scopes.length; i++) { 104 assertEquals(i, response.body.scopes[i].index); 105 assertEquals(scopes[i], response.body.scopes[i].type); 106 if (scopes[i] == debug.ScopeType.Local || 107 scopes[i] == debug.ScopeType.Closure) { 108 assertTrue(response.body.scopes[i].object.ref < 0); 109 } else { 110 assertTrue(response.body.scopes[i].object.ref >= 0); 111 } 112 var found = false; 113 for (var j = 0; j < response.refs.length && !found; j++) { 114 found = response.refs[j].handle == response.body.scopes[i].object.ref; 115 } 116 assertTrue(found, "Scope object " + response.body.scopes[i].object.ref + " not found"); 117 } 118} 119 120 121// Check that the content of the scope is as expected. For functions just check 122// that there is a function. 123function CheckScopeContent(content, number, exec_state) { 124 var scope = exec_state.frame().scope(number) 125 var count = 0; 126 for (var p in content) { 127 var property_mirror = scope.scopeObject().property(p); 128 assertFalse(property_mirror.isUndefined(), 'property ' + p + ' not found in scope'); 129 if (typeof(content[p]) === 'function') { 130 assertTrue(property_mirror.value().isFunction()); 131 } else { 132 assertEquals(content[p], property_mirror.value().value(), 'property ' + p + ' has unexpected value'); 133 } 134 count++; 135 } 136 137 // 'arguments' and might be exposed in the local and closure scope. Just 138 // ignore this. 139 var scope_size = scope.scopeObject().properties().length; 140 if (!scope.scopeObject().property('arguments').isUndefined()) { 141 scope_size--; 142 } 143 // Also ignore synthetic variable from catch block. 144 if (!scope.scopeObject().property('.catch-var').isUndefined()) { 145 scope_size--; 146 } 147 // Skip property with empty name. 148 if (!scope.scopeObject().property('').isUndefined()) { 149 scope_size--; 150 } 151 152 if (count != scope_size) { 153 print('Names found in scope:'); 154 var names = scope.scopeObject().propertyNames(); 155 for (var i = 0; i < names.length; i++) { 156 print(names[i]); 157 } 158 } 159 assertEquals(count, scope_size); 160 161 // Get the debug command processor. 162 var dcp = exec_state.debugCommandProcessor("unspecified_running_state"); 163 164 // Send a scope request for information on a single scope and check the 165 // result. 166 request_json = '{"seq":0,"type":"request","command":"scope","arguments":{"number":' 167 request_json += scope.scopeIndex(); 168 request_json += '}}' 169 var response_json = dcp.processDebugJSONRequest(request_json); 170 var response = JSON.parse(response_json); 171 assertEquals(scope.scopeType(), response.body.type); 172 assertEquals(number, response.body.index); 173 if (scope.scopeType() == debug.ScopeType.Local || 174 scope.scopeType() == debug.ScopeType.Closure) { 175 assertTrue(response.body.object.ref < 0); 176 } else { 177 assertTrue(response.body.object.ref >= 0); 178 } 179 var found = false; 180 for (var i = 0; i < response.refs.length && !found; i++) { 181 found = response.refs[i].handle == response.body.object.ref; 182 } 183 assertTrue(found, "Scope object " + response.body.object.ref + " not found"); 184} 185 186 187// Simple empty local scope. 188BeginTest("Local 1"); 189 190function local_1() { 191 debugger; 192} 193 194listener_delegate = function(exec_state) { 195 CheckScopeChain([debug.ScopeType.Local, 196 debug.ScopeType.Global], exec_state); 197 CheckScopeContent({}, 0, exec_state); 198} 199local_1() 200EndTest(); 201 202 203// Local scope with a parameter. 204BeginTest("Local 2"); 205 206function local_2(a) { 207 debugger; 208} 209 210listener_delegate = function(exec_state) { 211 CheckScopeChain([debug.ScopeType.Local, 212 debug.ScopeType.Global], exec_state); 213 CheckScopeContent({a:1}, 0, exec_state); 214} 215local_2(1) 216EndTest(); 217 218 219// Local scope with a parameter and a local variable. 220BeginTest("Local 3"); 221 222function local_3(a) { 223 var x = 3; 224 debugger; 225} 226 227listener_delegate = function(exec_state) { 228 CheckScopeChain([debug.ScopeType.Local, 229 debug.ScopeType.Global], exec_state); 230 CheckScopeContent({a:1,x:3}, 0, exec_state); 231} 232local_3(1) 233EndTest(); 234 235 236// Local scope with parameters and local variables. 237BeginTest("Local 4"); 238 239function local_4(a, b) { 240 var x = 3; 241 var y = 4; 242 debugger; 243} 244 245listener_delegate = function(exec_state) { 246 CheckScopeChain([debug.ScopeType.Local, 247 debug.ScopeType.Global], exec_state); 248 CheckScopeContent({a:1,b:2,x:3,y:4}, 0, exec_state); 249} 250local_4(1, 2) 251EndTest(); 252 253 254// Empty local scope with use of eval. 255BeginTest("Local 5"); 256 257function local_5() { 258 eval(''); 259 debugger; 260} 261 262listener_delegate = function(exec_state) { 263 CheckScopeChain([debug.ScopeType.Local, 264 debug.ScopeType.Global], exec_state); 265 CheckScopeContent({}, 0, exec_state); 266} 267local_5() 268EndTest(); 269 270 271// Local introducing local variable using eval. 272BeginTest("Local 6"); 273 274function local_6() { 275 eval('var i = 5'); 276 debugger; 277} 278 279listener_delegate = function(exec_state) { 280 CheckScopeChain([debug.ScopeType.Local, 281 debug.ScopeType.Global], exec_state); 282 CheckScopeContent({i:5}, 0, exec_state); 283} 284local_6() 285EndTest(); 286 287 288// Local scope with parameters, local variables and local variable introduced 289// using eval. 290BeginTest("Local 7"); 291 292function local_7(a, b) { 293 var x = 3; 294 var y = 4; 295 eval('var i = 5'); 296 eval('var j = 6'); 297 debugger; 298} 299 300listener_delegate = function(exec_state) { 301 CheckScopeChain([debug.ScopeType.Local, 302 debug.ScopeType.Global], exec_state); 303 CheckScopeContent({a:1,b:2,x:3,y:4,i:5,j:6}, 0, exec_state); 304} 305local_7(1, 2) 306EndTest(); 307 308 309// Single empty with block. 310BeginTest("With 1"); 311 312function with_1() { 313 with({}) { 314 debugger; 315 } 316} 317 318listener_delegate = function(exec_state) { 319 CheckScopeChain([debug.ScopeType.With, 320 debug.ScopeType.Local, 321 debug.ScopeType.Global], exec_state); 322 CheckScopeContent({}, 0, exec_state); 323} 324with_1() 325EndTest(); 326 327 328// Nested empty with blocks. 329BeginTest("With 2"); 330 331function with_2() { 332 with({}) { 333 with({}) { 334 debugger; 335 } 336 } 337} 338 339listener_delegate = function(exec_state) { 340 CheckScopeChain([debug.ScopeType.With, 341 debug.ScopeType.With, 342 debug.ScopeType.Local, 343 debug.ScopeType.Global], exec_state); 344 CheckScopeContent({}, 0, exec_state); 345 CheckScopeContent({}, 1, exec_state); 346} 347with_2() 348EndTest(); 349 350 351// With block using an in-place object literal. 352BeginTest("With 3"); 353 354function with_3() { 355 with({a:1,b:2}) { 356 debugger; 357 } 358} 359 360listener_delegate = function(exec_state) { 361 CheckScopeChain([debug.ScopeType.With, 362 debug.ScopeType.Local, 363 debug.ScopeType.Global], exec_state); 364 CheckScopeContent({a:1,b:2}, 0, exec_state); 365} 366with_3() 367EndTest(); 368 369 370// Nested with blocks using in-place object literals. 371BeginTest("With 4"); 372 373function with_4() { 374 with({a:1,b:2}) { 375 with({a:2,b:1}) { 376 debugger; 377 } 378 } 379} 380 381listener_delegate = function(exec_state) { 382 CheckScopeChain([debug.ScopeType.With, 383 debug.ScopeType.With, 384 debug.ScopeType.Local, 385 debug.ScopeType.Global], exec_state); 386 CheckScopeContent({a:2,b:1}, 0, exec_state); 387 CheckScopeContent({a:1,b:2}, 1, exec_state); 388} 389with_4() 390EndTest(); 391 392 393// Nested with blocks using existing object. 394BeginTest("With 5"); 395 396var with_object = {c:3,d:4}; 397function with_5() { 398 with(with_object) { 399 with(with_object) { 400 debugger; 401 } 402 } 403} 404 405listener_delegate = function(exec_state) { 406 CheckScopeChain([debug.ScopeType.With, 407 debug.ScopeType.With, 408 debug.ScopeType.Local, 409 debug.ScopeType.Global], exec_state); 410 CheckScopeContent(with_object, 0, exec_state); 411 CheckScopeContent(with_object, 1, exec_state); 412 assertEquals(exec_state.frame().scope(0).scopeObject(), exec_state.frame().scope(1).scopeObject()); 413 assertEquals(with_object, exec_state.frame().scope(1).scopeObject().value()); 414} 415with_5() 416EndTest(); 417 418 419// Simple closure formed by returning an inner function referering the outer 420// functions arguments. 421BeginTest("Closure 1"); 422 423function closure_1(a) { 424 function f() { 425 debugger; 426 return a; 427 }; 428 return f; 429} 430 431listener_delegate = function(exec_state) { 432 CheckScopeChain([debug.ScopeType.Local, 433 debug.ScopeType.Closure, 434 debug.ScopeType.Global], exec_state); 435 CheckScopeContent({a:1}, 1, exec_state); 436} 437closure_1(1)() 438EndTest(); 439 440 441// Simple closure formed by returning an inner function referering the outer 442// functions arguments. Due to VM optimizations parts of the actual closure is 443// missing from the debugger information. 444BeginTest("Closure 2"); 445 446function closure_2(a, b) { 447 var x = a + 2; 448 var y = b + 2; 449 function f() { 450 debugger; 451 return a + x; 452 }; 453 return f; 454} 455 456listener_delegate = function(exec_state) { 457 CheckScopeChain([debug.ScopeType.Local, 458 debug.ScopeType.Closure, 459 debug.ScopeType.Global], exec_state); 460 CheckScopeContent({a:1,x:3}, 1, exec_state); 461} 462closure_2(1, 2)() 463EndTest(); 464 465 466// Simple closure formed by returning an inner function referering the outer 467// functions arguments. Using all arguments and locals from the outer function 468// in the inner function makes these part of the debugger information on the 469// closure. 470BeginTest("Closure 3"); 471 472function closure_3(a, b) { 473 var x = a + 2; 474 var y = b + 2; 475 function f() { 476 debugger; 477 return a + b + x + y; 478 }; 479 return f; 480} 481 482listener_delegate = function(exec_state) { 483 CheckScopeChain([debug.ScopeType.Local, 484 debug.ScopeType.Closure, 485 debug.ScopeType.Global], exec_state); 486 CheckScopeContent({a:1,b:2,x:3,y:4}, 1, exec_state); 487} 488closure_3(1, 2)() 489EndTest(); 490 491 492 493// Simple closure formed by returning an inner function referering the outer 494// functions arguments. Using all arguments and locals from the outer function 495// in the inner function makes these part of the debugger information on the 496// closure. Use the inner function as well... 497BeginTest("Closure 4"); 498 499function closure_4(a, b) { 500 var x = a + 2; 501 var y = b + 2; 502 function f() { 503 debugger; 504 if (f) { 505 return a + b + x + y; 506 } 507 }; 508 return f; 509} 510 511listener_delegate = function(exec_state) { 512 CheckScopeChain([debug.ScopeType.Local, 513 debug.ScopeType.Closure, 514 debug.ScopeType.Global], exec_state); 515 CheckScopeContent({a:1,b:2,x:3,y:4,f:function(){}}, 1, exec_state); 516} 517closure_4(1, 2)() 518EndTest(); 519 520 521 522// Simple closure formed by returning an inner function referering the outer 523// functions arguments. In the presence of eval all arguments and locals 524// (including the inner function itself) from the outer function becomes part of 525// the debugger infformation on the closure. 526BeginTest("Closure 5"); 527 528function closure_5(a, b) { 529 var x = 3; 530 var y = 4; 531 function f() { 532 eval(''); 533 debugger; 534 return 1; 535 }; 536 return f; 537} 538 539listener_delegate = function(exec_state) { 540 CheckScopeChain([debug.ScopeType.Local, 541 debug.ScopeType.Closure, 542 debug.ScopeType.Global], exec_state); 543 CheckScopeContent({a:1,b:2,x:3,y:4,f:function(){}}, 1, exec_state); 544} 545closure_5(1, 2)() 546EndTest(); 547 548 549// Two closures. Due to optimizations only the parts actually used are provided 550// through the debugger information. 551BeginTest("Closure 6"); 552function closure_6(a, b) { 553 function f(a, b) { 554 var x = 3; 555 var y = 4; 556 return function() { 557 var x = 3; 558 var y = 4; 559 debugger; 560 some_global = a; 561 return f; 562 } 563 } 564 return f(a, b); 565} 566 567listener_delegate = function(exec_state) { 568 CheckScopeChain([debug.ScopeType.Local, 569 debug.ScopeType.Closure, 570 debug.ScopeType.Closure, 571 debug.ScopeType.Global], exec_state); 572 CheckScopeContent({a:1}, 1, exec_state); 573 CheckScopeContent({f:function(){}}, 2, exec_state); 574} 575closure_6(1, 2)() 576EndTest(); 577 578 579// Two closures. In the presence of eval all information is provided as the 580// compiler cannot determine which parts are used. 581BeginTest("Closure 7"); 582function closure_7(a, b) { 583 var x = 3; 584 var y = 4; 585 eval('var i = 5'); 586 eval('var j = 6'); 587 function f(a, b) { 588 var x = 3; 589 var y = 4; 590 eval('var i = 5'); 591 eval('var j = 6'); 592 return function() { 593 debugger; 594 some_global = a; 595 return f; 596 } 597 } 598 return f(a, b); 599} 600 601listener_delegate = function(exec_state) { 602 CheckScopeChain([debug.ScopeType.Local, 603 debug.ScopeType.Closure, 604 debug.ScopeType.Closure, 605 debug.ScopeType.Global], exec_state); 606 CheckScopeContent({}, 0, exec_state); 607 CheckScopeContent({a:1,b:2,x:3,y:4,i:5,j:6}, 1, exec_state); 608 CheckScopeContent({a:1,b:2,x:3,y:4,i:5,j:6,f:function(){}}, 2, exec_state); 609} 610closure_7(1, 2)() 611EndTest(); 612 613 614// Closure that may be optimized out. 615BeginTest("Closure 8"); 616function closure_8() { 617 (function inner(x) { 618 debugger; 619 })(2); 620} 621 622listener_delegate = function(exec_state) { 623 CheckScopeChain([debug.ScopeType.Local, 624 debug.ScopeType.Global], exec_state); 625 CheckScopeContent({x: 2}, 0, exec_state); 626} 627closure_8(); 628EndTest(); 629 630 631BeginTest("Closure 9"); 632function closure_9() { 633 eval("var y = 1;"); 634 eval("var z = 1;"); 635 (function inner(x) { 636 y++; 637 z++; 638 debugger; 639 })(2); 640} 641 642listener_delegate = function(exec_state) { 643 CheckScopeChain([debug.ScopeType.Local, 644 debug.ScopeType.Closure, 645 debug.ScopeType.Global], exec_state); 646} 647closure_9(); 648EndTest(); 649 650 651// Test a mixture of scopes. 652BeginTest("The full monty"); 653function the_full_monty(a, b) { 654 var x = 3; 655 var y = 4; 656 eval('var i = 5'); 657 eval('var j = 6'); 658 function f(a, b) { 659 var x = 9; 660 var y = 10; 661 eval('var i = 11'); 662 eval('var j = 12'); 663 with ({j:13}){ 664 return function() { 665 var x = 14; 666 with ({a:15}) { 667 with ({b:16}) { 668 debugger; 669 some_global = a; 670 return f; 671 } 672 } 673 } 674 } 675 } 676 return f(a, b); 677} 678 679listener_delegate = function(exec_state) { 680 CheckScopeChain([debug.ScopeType.With, 681 debug.ScopeType.With, 682 debug.ScopeType.Local, 683 debug.ScopeType.With, 684 debug.ScopeType.Closure, 685 debug.ScopeType.Closure, 686 debug.ScopeType.Global], exec_state); 687 CheckScopeContent({b:16}, 0, exec_state); 688 CheckScopeContent({a:15}, 1, exec_state); 689 CheckScopeContent({x:14}, 2, exec_state); 690 CheckScopeContent({j:13}, 3, exec_state); 691 CheckScopeContent({a:1,b:2,x:9,y:10,i:11,j:12}, 4, exec_state); 692 CheckScopeContent({a:1,b:2,x:3,y:4,i:5,j:6,f:function(){}}, 5, exec_state); 693} 694the_full_monty(1, 2)() 695EndTest(); 696 697 698BeginTest("Closure inside With 1"); 699function closure_in_with_1() { 700 with({x:1}) { 701 (function inner(x) { 702 debugger; 703 })(2); 704 } 705} 706 707listener_delegate = function(exec_state) { 708 CheckScopeChain([debug.ScopeType.Local, 709 debug.ScopeType.With, 710 debug.ScopeType.Closure, 711 debug.ScopeType.Global], exec_state); 712 CheckScopeContent({x: 2}, 0, exec_state); 713} 714closure_in_with_1(); 715EndTest(); 716 717 718BeginTest("Closure inside With 2"); 719function closure_in_with_2() { 720 with({x:1}) { 721 (function inner(x) { 722 with({x:3}) { 723 debugger; 724 } 725 })(2); 726 } 727} 728 729listener_delegate = function(exec_state) { 730 CheckScopeChain([debug.ScopeType.With, 731 debug.ScopeType.Local, 732 debug.ScopeType.With, 733 debug.ScopeType.Closure, 734 debug.ScopeType.Global], exec_state); 735 CheckScopeContent({x: 3}, 0, exec_state); 736 CheckScopeContent({x: 2}, 1, exec_state); 737 CheckScopeContent({x: 1}, 2, exec_state); 738} 739closure_in_with_2(); 740EndTest(); 741 742 743BeginTest("Closure inside With 3"); 744function createClosure(a) { 745 var b = a + 1; 746 return function closure() { 747 var c = b; 748 (function inner(x) { 749 with({x:c}) { 750 debugger; 751 } 752 })(2); 753 } 754} 755 756function closure_in_with_3() { 757 var f = createClosure(0); 758 f(); 759} 760 761listener_delegate = function(exec_state) { 762 CheckScopeChain([debug.ScopeType.With, 763 debug.ScopeType.Local, 764 debug.ScopeType.Closure, 765 debug.ScopeType.Closure, 766 debug.ScopeType.Global], exec_state); 767} 768closure_in_with_3(); 769EndTest(); 770 771 772// Test global scope. 773BeginTest("Global"); 774listener_delegate = function(exec_state) { 775 CheckScopeChain([debug.ScopeType.Global], exec_state); 776} 777debugger; 778EndTest(); 779 780 781BeginTest("Catch block 1"); 782function catch_block_1() { 783 try { 784 throw 'Exception'; 785 } catch (e) { 786 debugger; 787 } 788}; 789 790 791listener_delegate = function(exec_state) { 792 CheckScopeChain([debug.ScopeType.Catch, 793 debug.ScopeType.Local, 794 debug.ScopeType.Global], exec_state); 795 CheckScopeContent({e:'Exception'}, 0, exec_state); 796} 797catch_block_1() 798EndTest(); 799 800 801BeginTest("Catch block 2"); 802function catch_block_2() { 803 try { 804 throw 'Exception'; 805 } catch (e) { 806 with({n:10}) { 807 debugger; 808 } 809 } 810}; 811 812 813listener_delegate = function(exec_state) { 814 CheckScopeChain([debug.ScopeType.With, 815 debug.ScopeType.Catch, 816 debug.ScopeType.Local, 817 debug.ScopeType.Global], exec_state); 818 CheckScopeContent({n:10}, 0, exec_state); 819 CheckScopeContent({e:'Exception'}, 1, exec_state); 820} 821catch_block_2() 822EndTest(); 823 824 825BeginTest("Catch block 3"); 826function catch_block_3() { 827 // Do eval to dynamically declare a local variable so that the context's 828 // extension slot is initialized with JSContextExtensionObject. 829 eval("var y = 78;"); 830 try { 831 throw 'Exception'; 832 } catch (e) { 833 debugger; 834 } 835}; 836 837 838listener_delegate = function(exec_state) { 839 CheckScopeChain([debug.ScopeType.Catch, 840 debug.ScopeType.Local, 841 debug.ScopeType.Global], exec_state); 842 CheckScopeContent({e:'Exception'}, 0, exec_state); 843 CheckScopeContent({y:78}, 1, exec_state); 844} 845catch_block_3() 846EndTest(); 847 848 849BeginTest("Catch block 4"); 850function catch_block_4() { 851 // Do eval to dynamically declare a local variable so that the context's 852 // extension slot is initialized with JSContextExtensionObject. 853 eval("var y = 98;"); 854 try { 855 throw 'Exception'; 856 } catch (e) { 857 with({n:10}) { 858 debugger; 859 } 860 } 861}; 862 863listener_delegate = function(exec_state) { 864 CheckScopeChain([debug.ScopeType.With, 865 debug.ScopeType.Catch, 866 debug.ScopeType.Local, 867 debug.ScopeType.Global], exec_state); 868 CheckScopeContent({n:10}, 0, exec_state); 869 CheckScopeContent({e:'Exception'}, 1, exec_state); 870 CheckScopeContent({y:98}, 2, exec_state); 871} 872catch_block_4() 873EndTest(); 874 875 876assertEquals(begin_test_count, break_count, 'one or more tests did not enter the debugger'); 877assertEquals(begin_test_count, end_test_count, 'one or more tests did not have its result checked'); 878