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