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