Home | History | Annotate | Download | only in mjsunit
      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.
     33 var Debug = debug.Debug;
     34 
     35 var test_name;
     36 var listener_delegate;
     37 var listener_called;
     38 var exception;
     39 var begin_test_count = 0;
     40 var end_test_count = 0;
     41 var break_count = 0;
     42 
     43 
     44 // Debug event listener which delegates.
     45 function 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.
     58 Debug.setListener(listener);
     59 
     60 
     61 // Initialize for a new test.
     62 function 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.
     72 function 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.
     80 function 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 
     87 function 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.
    101 function 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.
    149 function 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.
    210 BeginTest("Local 1");
    211 
    212 function local_1() {
    213   debugger;
    214 }
    215 
    216 listener_delegate = function(exec_state) {
    217   CheckScopeChain([debug.ScopeType.Local,
    218                    debug.ScopeType.Global], exec_state);
    219   CheckScopeContent({}, 0, exec_state);
    220 };
    221 local_1();
    222 EndTest();
    223 
    224 
    225 // Local scope with a parameter.
    226 BeginTest("Local 2");
    227 
    228 function local_2(a) {
    229   debugger;
    230 }
    231 
    232 listener_delegate = function(exec_state) {
    233   CheckScopeChain([debug.ScopeType.Local,
    234                    debug.ScopeType.Global], exec_state);
    235   CheckScopeContent({a:1}, 0, exec_state);
    236 };
    237 local_2(1);
    238 EndTest();
    239 
    240 
    241 // Local scope with a parameter and a local variable.
    242 BeginTest("Local 3");
    243 
    244 function local_3(a) {
    245   var x = 3;
    246   debugger;
    247 }
    248 
    249 listener_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 };
    254 local_3(1);
    255 EndTest();
    256 
    257 
    258 // Local scope with parameters and local variables.
    259 BeginTest("Local 4");
    260 
    261 function local_4(a, b) {
    262   var x = 3;
    263   var y = 4;
    264   debugger;
    265 }
    266 
    267 listener_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 };
    272 local_4(1, 2);
    273 EndTest();
    274 
    275 
    276 // Empty local scope with use of eval.
    277 BeginTest("Local 5");
    278 
    279 function local_5() {
    280   eval('');
    281   debugger;
    282 }
    283 
    284 listener_delegate = function(exec_state) {
    285   CheckScopeChain([debug.ScopeType.Local,
    286                    debug.ScopeType.Global], exec_state);
    287   CheckScopeContent({}, 0, exec_state);
    288 };
    289 local_5();
    290 EndTest();
    291 
    292 
    293 // Local introducing local variable using eval.
    294 BeginTest("Local 6");
    295 
    296 function local_6() {
    297   eval('var i = 5');
    298   debugger;
    299 }
    300 
    301 listener_delegate = function(exec_state) {
    302   CheckScopeChain([debug.ScopeType.Local,
    303                    debug.ScopeType.Global], exec_state);
    304   CheckScopeContent({i:5}, 0, exec_state);
    305 };
    306 local_6();
    307 EndTest();
    308 
    309 
    310 // Local scope with parameters, local variables and local variable introduced
    311 // using eval.
    312 BeginTest("Local 7");
    313 
    314 function 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 
    322 listener_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 };
    327 local_7(1, 2);
    328 EndTest();
    329 
    330 
    331 // Single empty with block.
    332 BeginTest("With 1");
    333 
    334 function with_1() {
    335   with({}) {
    336     debugger;
    337   }
    338 }
    339 
    340 listener_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 };
    346 with_1();
    347 EndTest();
    348 
    349 
    350 // Nested empty with blocks.
    351 BeginTest("With 2");
    352 
    353 function with_2() {
    354   with({}) {
    355     with({}) {
    356       debugger;
    357     }
    358   }
    359 }
    360 
    361 listener_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 };
    369 with_2();
    370 EndTest();
    371 
    372 
    373 // With block using an in-place object literal.
    374 BeginTest("With 3");
    375 
    376 function with_3() {
    377   with({a:1,b:2}) {
    378     debugger;
    379   }
    380 }
    381 
    382 listener_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 };
    388 with_3();
    389 EndTest();
    390 
    391 
    392 // Nested with blocks using in-place object literals.
    393 BeginTest("With 4");
    394 
    395 function with_4() {
    396   with({a:1,b:2}) {
    397     with({a:2,b:1}) {
    398       debugger;
    399     }
    400   }
    401 }
    402 
    403 listener_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 };
    411 with_4();
    412 EndTest();
    413 
    414 
    415 // Nested with blocks using existing object.
    416 BeginTest("With 5");
    417 
    418 var with_object = {c:3,d:4};
    419 function with_5() {
    420   with(with_object) {
    421     with(with_object) {
    422       debugger;
    423     }
    424   }
    425 }
    426 
    427 listener_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 };
    437 with_5();
    438 EndTest();
    439 
    440 
    441 // Nested with blocks using existing object in global code.
    442 BeginTest("With 6");
    443 listener_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 
    453 var with_object = {c:3,d:4};
    454 with(with_object) {
    455   with(with_object) {
    456     debugger;
    457   }
    458 }
    459 EndTest();
    460 
    461 
    462 // With block in function that is marked for optimization while being executed.
    463 BeginTest("With 7");
    464 
    465 function with_7() {
    466   with({}) {
    467     %OptimizeFunctionOnNextCall(with_7);
    468     debugger;
    469   }
    470 }
    471 
    472 listener_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 };
    478 with_7();
    479 EndTest();
    480 
    481 
    482 // Simple closure formed by returning an inner function referering the outer
    483 // functions arguments.
    484 BeginTest("Closure 1");
    485 
    486 function closure_1(a) {
    487   function f() {
    488     debugger;
    489     return a;
    490   };
    491   return f;
    492 }
    493 
    494 listener_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 };
    500 closure_1(1)();
    501 EndTest();
    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.
    507 BeginTest("Closure 2");
    508 
    509 function 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 
    519 listener_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 };
    525 closure_2(1, 2)();
    526 EndTest();
    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.
    533 BeginTest("Closure 3");
    534 
    535 function 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 
    545 listener_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 };
    551 closure_3(1, 2)();
    552 EndTest();
    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...
    560 BeginTest("Closure 4");
    561 
    562 function 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 
    574 listener_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 };
    580 closure_4(1, 2)();
    581 EndTest();
    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.
    589 BeginTest("Closure 5");
    590 
    591 function 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 
    602 listener_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 };
    608 closure_5(1, 2)();
    609 EndTest();
    610 
    611 
    612 // Two closures. Due to optimizations only the parts actually used are provided
    613 // through the debugger information.
    614 BeginTest("Closure 6");
    615 function 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 
    630 listener_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 };
    638 closure_6(1, 2)();
    639 EndTest();
    640 
    641 
    642 // Two closures. In the presence of eval all information is provided as the
    643 // compiler cannot determine which parts are used.
    644 BeginTest("Closure 7");
    645 function 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 
    664 listener_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 };
    673 closure_7(1, 2)();
    674 EndTest();
    675 
    676 
    677 // Closure that may be optimized out.
    678 BeginTest("Closure 8");
    679 function closure_8() {
    680   (function inner(x) {
    681     debugger;
    682   })(2);
    683 }
    684 
    685 listener_delegate = function(exec_state) {
    686   CheckScopeChain([debug.ScopeType.Local,
    687                    debug.ScopeType.Global], exec_state);
    688   CheckScopeContent({x: 2}, 0, exec_state);
    689 };
    690 closure_8();
    691 EndTest();
    692 
    693 
    694 BeginTest("Closure 9");
    695 function 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 
    705 listener_delegate = function(exec_state) {
    706   CheckScopeChain([debug.ScopeType.Local,
    707                    debug.ScopeType.Closure,
    708                    debug.ScopeType.Global], exec_state);
    709 };
    710 closure_9();
    711 EndTest();
    712 
    713 
    714 // Test a mixture of scopes.
    715 BeginTest("The full monty");
    716 function 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 
    742 listener_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 };
    757 the_full_monty(1, 2)();
    758 EndTest();
    759 
    760 
    761 BeginTest("Closure inside With 1");
    762 function closure_in_with_1() {
    763   with({x:1}) {
    764     (function inner(x) {
    765       debugger;
    766     })(2);
    767   }
    768 }
    769 
    770 listener_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 };
    777 closure_in_with_1();
    778 EndTest();
    779 
    780 
    781 BeginTest("Closure inside With 2");
    782 function closure_in_with_2() {
    783   with({x:1}) {
    784     (function inner(x) {
    785       with({x:3}) {
    786         debugger;
    787       }
    788     })(2);
    789   }
    790 }
    791 
    792 listener_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 };
    802 closure_in_with_2();
    803 EndTest();
    804 
    805 
    806 BeginTest("Closure inside With 3");
    807 function 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 
    819 function closure_in_with_3() {
    820   var f = createClosure(0);
    821   f();
    822 }
    823 
    824 listener_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 }
    831 closure_in_with_3();
    832 EndTest();
    833 
    834 
    835 BeginTest("Closure inside With 4");
    836 listener_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 
    844 with({x:1}) {
    845   (function(x) {
    846     debugger;
    847   })(2);
    848 }
    849 EndTest();
    850 
    851 
    852 // Test global scope.
    853 BeginTest("Global");
    854 listener_delegate = function(exec_state) {
    855   CheckScopeChain([debug.ScopeType.Global], exec_state);
    856 };
    857 debugger;
    858 EndTest();
    859 
    860 
    861 BeginTest("Catch block 1");
    862 function catch_block_1() {
    863   try {
    864     throw 'Exception';
    865   } catch (e) {
    866     debugger;
    867   }
    868 };
    869 
    870 
    871 listener_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 };
    877 catch_block_1();
    878 EndTest();
    879 
    880 
    881 BeginTest("Catch block 2");
    882 function catch_block_2() {
    883   try {
    884     throw 'Exception';
    885   } catch (e) {
    886     with({n:10}) {
    887       debugger;
    888     }
    889   }
    890 };
    891 
    892 
    893 listener_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 };
    901 catch_block_2();
    902 EndTest();
    903 
    904 
    905 BeginTest("Catch block 3");
    906 function 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 
    918 listener_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 };
    925 catch_block_3();
    926 EndTest();
    927 
    928 
    929 BeginTest("Catch block 4");
    930 function 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 
    943 listener_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 };
    952 catch_block_4();
    953 EndTest();
    954 
    955 
    956 // Test catch in global scope.
    957 BeginTest("Catch block 5");
    958 listener_delegate = function(exec_state) {
    959   CheckScopeChain([debug.ScopeType.Catch,
    960                    debug.ScopeType.Global], exec_state);
    961   CheckScopeContent({e:'Exception'}, 0, exec_state);
    962 };
    963 
    964 try {
    965   throw 'Exception';
    966 } catch (e) {
    967   debugger;
    968 }
    969 
    970 EndTest();
    971 
    972 
    973 // Closure inside catch in global code.
    974 BeginTest("Catch block 6");
    975 listener_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 
    983 try {
    984   throw 'Exception';
    985 } catch (e) {
    986   (function(x) {
    987     debugger;
    988   })(2);
    989 }
    990 EndTest();
    991 
    992 
    993 // Catch block in function that is marked for optimization while being executed.
    994 BeginTest("Catch block 7");
    995 function catch_block_7() {
    996   %OptimizeFunctionOnNextCall(catch_block_7);
    997   try {
    998     throw 'Exception';
    999   } catch (e) {
   1000     debugger;
   1001   }
   1002 };
   1003 
   1004 
   1005 listener_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 };
   1011 catch_block_7();
   1012 EndTest();
   1013 
   1014 
   1015 assertEquals(begin_test_count, break_count,
   1016              'one or more tests did not enter the debugger');
   1017 assertEquals(begin_test_count, end_test_count,
   1018              'one or more tests did not have its result checked');
   1019