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