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. 34 Debug = debug.Debug 35 36 var name; 37 var listener_delegate; 38 var listener_called; 39 var exception; 40 var begin_test_count = 0; 41 var end_test_count = 0; 42 var break_count = 0; 43 44 45 // Debug event listener which delegates. 46 function 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. 59 Debug.setListener(listener); 60 61 62 // Initialize for a noew test. 63 function 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. 73 function 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. 81 function 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. 123 function 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. 188 BeginTest("Local 1"); 189 190 function local_1() { 191 debugger; 192 } 193 194 listener_delegate = function(exec_state) { 195 CheckScopeChain([debug.ScopeType.Local, 196 debug.ScopeType.Global], exec_state); 197 CheckScopeContent({}, 0, exec_state); 198 } 199 local_1() 200 EndTest(); 201 202 203 // Local scope with a parameter. 204 BeginTest("Local 2"); 205 206 function local_2(a) { 207 debugger; 208 } 209 210 listener_delegate = function(exec_state) { 211 CheckScopeChain([debug.ScopeType.Local, 212 debug.ScopeType.Global], exec_state); 213 CheckScopeContent({a:1}, 0, exec_state); 214 } 215 local_2(1) 216 EndTest(); 217 218 219 // Local scope with a parameter and a local variable. 220 BeginTest("Local 3"); 221 222 function local_3(a) { 223 var x = 3; 224 debugger; 225 } 226 227 listener_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 } 232 local_3(1) 233 EndTest(); 234 235 236 // Local scope with parameters and local variables. 237 BeginTest("Local 4"); 238 239 function local_4(a, b) { 240 var x = 3; 241 var y = 4; 242 debugger; 243 } 244 245 listener_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 } 250 local_4(1, 2) 251 EndTest(); 252 253 254 // Empty local scope with use of eval. 255 BeginTest("Local 5"); 256 257 function local_5() { 258 eval(''); 259 debugger; 260 } 261 262 listener_delegate = function(exec_state) { 263 CheckScopeChain([debug.ScopeType.Local, 264 debug.ScopeType.Global], exec_state); 265 CheckScopeContent({}, 0, exec_state); 266 } 267 local_5() 268 EndTest(); 269 270 271 // Local introducing local variable using eval. 272 BeginTest("Local 6"); 273 274 function local_6() { 275 eval('var i = 5'); 276 debugger; 277 } 278 279 listener_delegate = function(exec_state) { 280 CheckScopeChain([debug.ScopeType.Local, 281 debug.ScopeType.Global], exec_state); 282 CheckScopeContent({i:5}, 0, exec_state); 283 } 284 local_6() 285 EndTest(); 286 287 288 // Local scope with parameters, local variables and local variable introduced 289 // using eval. 290 BeginTest("Local 7"); 291 292 function 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 300 listener_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 } 305 local_7(1, 2) 306 EndTest(); 307 308 309 // Single empty with block. 310 BeginTest("With 1"); 311 312 function with_1() { 313 with({}) { 314 debugger; 315 } 316 } 317 318 listener_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 } 324 with_1() 325 EndTest(); 326 327 328 // Nested empty with blocks. 329 BeginTest("With 2"); 330 331 function with_2() { 332 with({}) { 333 with({}) { 334 debugger; 335 } 336 } 337 } 338 339 listener_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 } 347 with_2() 348 EndTest(); 349 350 351 // With block using an in-place object literal. 352 BeginTest("With 3"); 353 354 function with_3() { 355 with({a:1,b:2}) { 356 debugger; 357 } 358 } 359 360 listener_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 } 366 with_3() 367 EndTest(); 368 369 370 // Nested with blocks using in-place object literals. 371 BeginTest("With 4"); 372 373 function with_4() { 374 with({a:1,b:2}) { 375 with({a:2,b:1}) { 376 debugger; 377 } 378 } 379 } 380 381 listener_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 } 389 with_4() 390 EndTest(); 391 392 393 // Nested with blocks using existing object. 394 BeginTest("With 5"); 395 396 var with_object = {c:3,d:4}; 397 function with_5() { 398 with(with_object) { 399 with(with_object) { 400 debugger; 401 } 402 } 403 } 404 405 listener_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 } 415 with_5() 416 EndTest(); 417 418 419 // Simple closure formed by returning an inner function referering the outer 420 // functions arguments. 421 BeginTest("Closure 1"); 422 423 function closure_1(a) { 424 function f() { 425 debugger; 426 return a; 427 }; 428 return f; 429 } 430 431 listener_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 } 437 closure_1(1)() 438 EndTest(); 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. 444 BeginTest("Closure 2"); 445 446 function 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 456 listener_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 } 462 closure_2(1, 2)() 463 EndTest(); 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. 470 BeginTest("Closure 3"); 471 472 function 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 482 listener_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 } 488 closure_3(1, 2)() 489 EndTest(); 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... 497 BeginTest("Closure 4"); 498 499 function 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 511 listener_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 } 517 closure_4(1, 2)() 518 EndTest(); 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. 526 BeginTest("Closure 5"); 527 528 function 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 539 listener_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 } 545 closure_5(1, 2)() 546 EndTest(); 547 548 549 // Two closures. Due to optimizations only the parts actually used are provided 550 // through the debugger information. 551 BeginTest("Closure 6"); 552 function 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 567 listener_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 } 575 closure_6(1, 2)() 576 EndTest(); 577 578 579 // Two closures. In the presence of eval all information is provided as the 580 // compiler cannot determine which parts are used. 581 BeginTest("Closure 7"); 582 function 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 601 listener_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 } 610 closure_7(1, 2)() 611 EndTest(); 612 613 614 // Closure that may be optimized out. 615 BeginTest("Closure 8"); 616 function closure_8() { 617 (function inner(x) { 618 debugger; 619 })(2); 620 } 621 622 listener_delegate = function(exec_state) { 623 CheckScopeChain([debug.ScopeType.Local, 624 debug.ScopeType.Global], exec_state); 625 CheckScopeContent({x: 2}, 0, exec_state); 626 } 627 closure_8(); 628 EndTest(); 629 630 631 BeginTest("Closure 9"); 632 function 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 642 listener_delegate = function(exec_state) { 643 CheckScopeChain([debug.ScopeType.Local, 644 debug.ScopeType.Closure, 645 debug.ScopeType.Global], exec_state); 646 } 647 closure_9(); 648 EndTest(); 649 650 651 // Test a mixture of scopes. 652 BeginTest("The full monty"); 653 function 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 679 listener_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 } 694 the_full_monty(1, 2)() 695 EndTest(); 696 697 698 BeginTest("Closure inside With 1"); 699 function closure_in_with_1() { 700 with({x:1}) { 701 (function inner(x) { 702 debugger; 703 })(2); 704 } 705 } 706 707 listener_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 } 714 closure_in_with_1(); 715 EndTest(); 716 717 718 BeginTest("Closure inside With 2"); 719 function closure_in_with_2() { 720 with({x:1}) { 721 (function inner(x) { 722 with({x:3}) { 723 debugger; 724 } 725 })(2); 726 } 727 } 728 729 listener_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 } 739 closure_in_with_2(); 740 EndTest(); 741 742 743 BeginTest("Closure inside With 3"); 744 function 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 756 function closure_in_with_3() { 757 var f = createClosure(0); 758 f(); 759 } 760 761 listener_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 } 768 closure_in_with_3(); 769 EndTest(); 770 771 772 // Test global scope. 773 BeginTest("Global"); 774 listener_delegate = function(exec_state) { 775 CheckScopeChain([debug.ScopeType.Global], exec_state); 776 } 777 debugger; 778 EndTest(); 779 780 781 BeginTest("Catch block 1"); 782 function catch_block_1() { 783 try { 784 throw 'Exception'; 785 } catch (e) { 786 debugger; 787 } 788 }; 789 790 791 listener_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 } 797 catch_block_1() 798 EndTest(); 799 800 801 BeginTest("Catch block 2"); 802 function catch_block_2() { 803 try { 804 throw 'Exception'; 805 } catch (e) { 806 with({n:10}) { 807 debugger; 808 } 809 } 810 }; 811 812 813 listener_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 } 821 catch_block_2() 822 EndTest(); 823 824 825 BeginTest("Catch block 3"); 826 function 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 838 listener_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 } 845 catch_block_3() 846 EndTest(); 847 848 849 BeginTest("Catch block 4"); 850 function 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 863 listener_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 } 872 catch_block_4() 873 EndTest(); 874 875 876 assertEquals(begin_test_count, break_count, 'one or more tests did not enter the debugger'); 877 assertEquals(begin_test_count, end_test_count, 'one or more tests did not have its result checked'); 878