blob: 1c23b0bf998e777334d9d767bdc860c601e855e6 [file] [log] [blame]
Ben Murdoch85b71792012-04-11 18:30:58 +01001// Copyright 2008 the V8 project authors. All rights reserved.
Steve Blocka7e24c12009-10-30 11:49:00 +00002// 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
Ben Murdoch85b71792012-04-11 18:30:58 +010028// Flags: --expose-debug-as debug
Steve Blocka7e24c12009-10-30 11:49:00 +000029// The functions used for testing backtraces. They are at the top to make the
30// testing of source line/column easier.
31
Ben Murdoch85b71792012-04-11 18:30:58 +010032
Steve Blocka7e24c12009-10-30 11:49:00 +000033// Get the Debug object exposed from the debug context global object.
Ben Murdoch85b71792012-04-11 18:30:58 +010034Debug = debug.Debug;
Steve Blocka7e24c12009-10-30 11:49:00 +000035
Ben Murdoch257744e2011-11-30 15:57:28 +000036var test_name;
Steve Blocka7e24c12009-10-30 11:49:00 +000037var listener_delegate;
38var listener_called;
39var exception;
40var begin_test_count = 0;
41var end_test_count = 0;
42var break_count = 0;
43
44
45// Debug event listener which delegates.
46function listener(event, exec_state, event_data, data) {
47 try {
48 if (event == Debug.DebugEvent.Break) {
49 break_count++;
50 listener_called = true;
Ben Murdoch257744e2011-11-30 15:57:28 +000051 listener_delegate(exec_state);
Steve Blocka7e24c12009-10-30 11:49:00 +000052 }
53 } catch (e) {
54 exception = e;
55 }
56}
57
58// Add the debug event listener.
59Debug.setListener(listener);
60
61
Ben Murdoch257744e2011-11-30 15:57:28 +000062// Initialize for a new test.
Steve Blocka7e24c12009-10-30 11:49:00 +000063function BeginTest(name) {
64 test_name = name;
65 listener_delegate = null;
66 listener_called = false;
67 exception = null;
68 begin_test_count++;
69}
70
71
72// Check result of a test.
73function EndTest() {
74 assertTrue(listener_called, "listerner not called for " + test_name);
Ben Murdoch257744e2011-11-30 15:57:28 +000075 assertNull(exception, test_name);
Steve Blocka7e24c12009-10-30 11:49:00 +000076 end_test_count++;
77}
78
79
80// Check that the scope chain contains the expected types of scopes.
81function CheckScopeChain(scopes, exec_state) {
82 assertEquals(scopes.length, exec_state.frame().scopeCount());
83 for (var i = 0; i < scopes.length; i++) {
84 var scope = exec_state.frame().scope(i);
85 assertTrue(scope.isScope());
86 assertEquals(scopes[i], scope.scopeType());
Steve Block6ded16b2010-05-10 14:33:55 +010087
Steve Blocka7e24c12009-10-30 11:49:00 +000088 // Check the global object when hitting the global scope.
89 if (scopes[i] == debug.ScopeType.Global) {
Ben Murdoch257744e2011-11-30 15:57:28 +000090 // Objects don't have same class (one is "global", other is "Object",
91 // so just check the properties directly.
92 assertPropertiesEqual(this, scope.scopeObject().value());
Steve Blocka7e24c12009-10-30 11:49:00 +000093 }
94 }
Steve Block6ded16b2010-05-10 14:33:55 +010095
Steve Blocka7e24c12009-10-30 11:49:00 +000096 // Get the debug command processor.
Steve Block3ce2e202009-11-05 08:53:23 +000097 var dcp = exec_state.debugCommandProcessor("unspecified_running_state");
Steve Block6ded16b2010-05-10 14:33:55 +010098
Steve Blocka7e24c12009-10-30 11:49:00 +000099 // Send a scopes request and check the result.
100 var json;
Ben Murdoch257744e2011-11-30 15:57:28 +0000101 var request_json = '{"seq":0,"type":"request","command":"scopes"}';
Steve Blocka7e24c12009-10-30 11:49:00 +0000102 var response_json = dcp.processDebugJSONRequest(request_json);
103 var response = JSON.parse(response_json);
104 assertEquals(scopes.length, response.body.scopes.length);
105 for (var i = 0; i < scopes.length; i++) {
106 assertEquals(i, response.body.scopes[i].index);
107 assertEquals(scopes[i], response.body.scopes[i].type);
108 if (scopes[i] == debug.ScopeType.Local ||
109 scopes[i] == debug.ScopeType.Closure) {
110 assertTrue(response.body.scopes[i].object.ref < 0);
111 } else {
112 assertTrue(response.body.scopes[i].object.ref >= 0);
113 }
114 var found = false;
115 for (var j = 0; j < response.refs.length && !found; j++) {
116 found = response.refs[j].handle == response.body.scopes[i].object.ref;
117 }
118 assertTrue(found, "Scope object " + response.body.scopes[i].object.ref + " not found");
119 }
120}
121
122
123// Check that the content of the scope is as expected. For functions just check
124// that there is a function.
125function CheckScopeContent(content, number, exec_state) {
Ben Murdoch257744e2011-11-30 15:57:28 +0000126 var scope = exec_state.frame().scope(number);
Steve Blocka7e24c12009-10-30 11:49:00 +0000127 var count = 0;
128 for (var p in content) {
129 var property_mirror = scope.scopeObject().property(p);
130 assertFalse(property_mirror.isUndefined(), 'property ' + p + ' not found in scope');
131 if (typeof(content[p]) === 'function') {
132 assertTrue(property_mirror.value().isFunction());
133 } else {
134 assertEquals(content[p], property_mirror.value().value(), 'property ' + p + ' has unexpected value');
135 }
136 count++;
137 }
Steve Block6ded16b2010-05-10 14:33:55 +0100138
Steve Blocka7e24c12009-10-30 11:49:00 +0000139 // 'arguments' and might be exposed in the local and closure scope. Just
140 // ignore this.
141 var scope_size = scope.scopeObject().properties().length;
142 if (!scope.scopeObject().property('arguments').isUndefined()) {
143 scope_size--;
144 }
145 // Also ignore synthetic variable from catch block.
146 if (!scope.scopeObject().property('.catch-var').isUndefined()) {
147 scope_size--;
148 }
Ben Murdoch8b112d22011-06-08 16:22:53 +0100149 // Skip property with empty name.
150 if (!scope.scopeObject().property('').isUndefined()) {
151 scope_size--;
152 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000153
154 if (count != scope_size) {
155 print('Names found in scope:');
156 var names = scope.scopeObject().propertyNames();
157 for (var i = 0; i < names.length; i++) {
158 print(names[i]);
159 }
160 }
161 assertEquals(count, scope_size);
162
163 // Get the debug command processor.
Steve Block3ce2e202009-11-05 08:53:23 +0000164 var dcp = exec_state.debugCommandProcessor("unspecified_running_state");
Steve Block6ded16b2010-05-10 14:33:55 +0100165
Steve Blocka7e24c12009-10-30 11:49:00 +0000166 // Send a scope request for information on a single scope and check the
167 // result.
Ben Murdoch257744e2011-11-30 15:57:28 +0000168 var request_json = '{"seq":0,"type":"request","command":"scope","arguments":{"number":';
Steve Blocka7e24c12009-10-30 11:49:00 +0000169 request_json += scope.scopeIndex();
Ben Murdoch257744e2011-11-30 15:57:28 +0000170 request_json += '}}';
Steve Blocka7e24c12009-10-30 11:49:00 +0000171 var response_json = dcp.processDebugJSONRequest(request_json);
172 var response = JSON.parse(response_json);
173 assertEquals(scope.scopeType(), response.body.type);
174 assertEquals(number, response.body.index);
175 if (scope.scopeType() == debug.ScopeType.Local ||
176 scope.scopeType() == debug.ScopeType.Closure) {
177 assertTrue(response.body.object.ref < 0);
178 } else {
179 assertTrue(response.body.object.ref >= 0);
180 }
181 var found = false;
182 for (var i = 0; i < response.refs.length && !found; i++) {
183 found = response.refs[i].handle == response.body.object.ref;
184 }
185 assertTrue(found, "Scope object " + response.body.object.ref + " not found");
186}
187
188
189// Simple empty local scope.
190BeginTest("Local 1");
191
192function local_1() {
193 debugger;
194}
195
196listener_delegate = function(exec_state) {
197 CheckScopeChain([debug.ScopeType.Local,
198 debug.ScopeType.Global], exec_state);
199 CheckScopeContent({}, 0, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000200};
201local_1();
Steve Blocka7e24c12009-10-30 11:49:00 +0000202EndTest();
203
204
205// Local scope with a parameter.
206BeginTest("Local 2");
207
208function local_2(a) {
209 debugger;
210}
211
212listener_delegate = function(exec_state) {
213 CheckScopeChain([debug.ScopeType.Local,
214 debug.ScopeType.Global], exec_state);
215 CheckScopeContent({a:1}, 0, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000216};
217local_2(1);
Steve Blocka7e24c12009-10-30 11:49:00 +0000218EndTest();
219
220
221// Local scope with a parameter and a local variable.
222BeginTest("Local 3");
223
224function local_3(a) {
225 var x = 3;
226 debugger;
227}
228
229listener_delegate = function(exec_state) {
230 CheckScopeChain([debug.ScopeType.Local,
231 debug.ScopeType.Global], exec_state);
232 CheckScopeContent({a:1,x:3}, 0, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000233};
234local_3(1);
Steve Blocka7e24c12009-10-30 11:49:00 +0000235EndTest();
236
237
238// Local scope with parameters and local variables.
239BeginTest("Local 4");
240
241function local_4(a, b) {
242 var x = 3;
243 var y = 4;
244 debugger;
245}
246
247listener_delegate = function(exec_state) {
248 CheckScopeChain([debug.ScopeType.Local,
249 debug.ScopeType.Global], exec_state);
250 CheckScopeContent({a:1,b:2,x:3,y:4}, 0, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000251};
252local_4(1, 2);
Steve Blocka7e24c12009-10-30 11:49:00 +0000253EndTest();
254
255
256// Empty local scope with use of eval.
257BeginTest("Local 5");
258
259function local_5() {
260 eval('');
261 debugger;
262}
263
264listener_delegate = function(exec_state) {
265 CheckScopeChain([debug.ScopeType.Local,
266 debug.ScopeType.Global], exec_state);
267 CheckScopeContent({}, 0, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000268};
269local_5();
Steve Blocka7e24c12009-10-30 11:49:00 +0000270EndTest();
271
272
273// Local introducing local variable using eval.
274BeginTest("Local 6");
275
276function local_6() {
277 eval('var i = 5');
278 debugger;
279}
280
281listener_delegate = function(exec_state) {
282 CheckScopeChain([debug.ScopeType.Local,
283 debug.ScopeType.Global], exec_state);
284 CheckScopeContent({i:5}, 0, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000285};
286local_6();
Steve Blocka7e24c12009-10-30 11:49:00 +0000287EndTest();
288
289
290// Local scope with parameters, local variables and local variable introduced
291// using eval.
292BeginTest("Local 7");
293
294function local_7(a, b) {
295 var x = 3;
296 var y = 4;
297 eval('var i = 5');
298 eval('var j = 6');
299 debugger;
300}
301
302listener_delegate = function(exec_state) {
303 CheckScopeChain([debug.ScopeType.Local,
304 debug.ScopeType.Global], exec_state);
305 CheckScopeContent({a:1,b:2,x:3,y:4,i:5,j:6}, 0, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000306};
307local_7(1, 2);
Steve Blocka7e24c12009-10-30 11:49:00 +0000308EndTest();
309
310
311// Single empty with block.
312BeginTest("With 1");
313
314function with_1() {
315 with({}) {
316 debugger;
317 }
318}
319
320listener_delegate = function(exec_state) {
321 CheckScopeChain([debug.ScopeType.With,
322 debug.ScopeType.Local,
323 debug.ScopeType.Global], exec_state);
324 CheckScopeContent({}, 0, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000325};
326with_1();
Steve Blocka7e24c12009-10-30 11:49:00 +0000327EndTest();
328
329
330// Nested empty with blocks.
331BeginTest("With 2");
332
333function with_2() {
334 with({}) {
335 with({}) {
336 debugger;
337 }
338 }
339}
340
341listener_delegate = function(exec_state) {
342 CheckScopeChain([debug.ScopeType.With,
343 debug.ScopeType.With,
344 debug.ScopeType.Local,
345 debug.ScopeType.Global], exec_state);
346 CheckScopeContent({}, 0, exec_state);
347 CheckScopeContent({}, 1, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000348};
349with_2();
Steve Blocka7e24c12009-10-30 11:49:00 +0000350EndTest();
351
352
353// With block using an in-place object literal.
354BeginTest("With 3");
355
356function with_3() {
357 with({a:1,b:2}) {
358 debugger;
359 }
360}
361
362listener_delegate = function(exec_state) {
363 CheckScopeChain([debug.ScopeType.With,
364 debug.ScopeType.Local,
365 debug.ScopeType.Global], exec_state);
366 CheckScopeContent({a:1,b:2}, 0, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000367};
368with_3();
Steve Blocka7e24c12009-10-30 11:49:00 +0000369EndTest();
370
371
372// Nested with blocks using in-place object literals.
373BeginTest("With 4");
374
375function with_4() {
376 with({a:1,b:2}) {
377 with({a:2,b:1}) {
378 debugger;
379 }
380 }
381}
382
383listener_delegate = function(exec_state) {
384 CheckScopeChain([debug.ScopeType.With,
385 debug.ScopeType.With,
386 debug.ScopeType.Local,
387 debug.ScopeType.Global], exec_state);
388 CheckScopeContent({a:2,b:1}, 0, exec_state);
389 CheckScopeContent({a:1,b:2}, 1, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000390};
391with_4();
Steve Blocka7e24c12009-10-30 11:49:00 +0000392EndTest();
393
394
395// Nested with blocks using existing object.
396BeginTest("With 5");
397
398var with_object = {c:3,d:4};
399function with_5() {
400 with(with_object) {
401 with(with_object) {
402 debugger;
403 }
404 }
405}
406
407listener_delegate = function(exec_state) {
408 CheckScopeChain([debug.ScopeType.With,
409 debug.ScopeType.With,
410 debug.ScopeType.Local,
411 debug.ScopeType.Global], exec_state);
412 CheckScopeContent(with_object, 0, exec_state);
413 CheckScopeContent(with_object, 1, exec_state);
414 assertEquals(exec_state.frame().scope(0).scopeObject(), exec_state.frame().scope(1).scopeObject());
415 assertEquals(with_object, exec_state.frame().scope(1).scopeObject().value());
Ben Murdoch257744e2011-11-30 15:57:28 +0000416};
417with_5();
Steve Blocka7e24c12009-10-30 11:49:00 +0000418EndTest();
419
420
Ben Murdoch589d6972011-11-30 16:04:58 +0000421// Nested with blocks using existing object in global code.
422BeginTest("With 6");
423listener_delegate = function(exec_state) {
424 CheckScopeChain([debug.ScopeType.With,
425 debug.ScopeType.With,
426 debug.ScopeType.Global], exec_state);
427 CheckScopeContent(with_object, 0, exec_state);
428 CheckScopeContent(with_object, 1, exec_state);
429 assertEquals(exec_state.frame().scope(0).scopeObject(), exec_state.frame().scope(1).scopeObject());
430 assertEquals(with_object, exec_state.frame().scope(1).scopeObject().value());
431};
432
433var with_object = {c:3,d:4};
434with(with_object) {
435 with(with_object) {
436 debugger;
437 }
438}
439EndTest();
440
441
Steve Blocka7e24c12009-10-30 11:49:00 +0000442// Simple closure formed by returning an inner function referering the outer
443// functions arguments.
444BeginTest("Closure 1");
445
446function closure_1(a) {
447 function f() {
448 debugger;
449 return a;
450 };
451 return f;
452}
453
454listener_delegate = function(exec_state) {
455 CheckScopeChain([debug.ScopeType.Local,
456 debug.ScopeType.Closure,
457 debug.ScopeType.Global], exec_state);
458 CheckScopeContent({a:1}, 1, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000459};
460closure_1(1)();
Steve Blocka7e24c12009-10-30 11:49:00 +0000461EndTest();
462
463
464// Simple closure formed by returning an inner function referering the outer
465// functions arguments. Due to VM optimizations parts of the actual closure is
466// missing from the debugger information.
467BeginTest("Closure 2");
468
469function closure_2(a, b) {
470 var x = a + 2;
471 var y = b + 2;
472 function f() {
473 debugger;
474 return a + x;
475 };
476 return f;
477}
478
479listener_delegate = function(exec_state) {
480 CheckScopeChain([debug.ScopeType.Local,
481 debug.ScopeType.Closure,
482 debug.ScopeType.Global], exec_state);
483 CheckScopeContent({a:1,x:3}, 1, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000484};
485closure_2(1, 2)();
Steve Blocka7e24c12009-10-30 11:49:00 +0000486EndTest();
487
488
489// Simple closure formed by returning an inner function referering the outer
490// functions arguments. Using all arguments and locals from the outer function
491// in the inner function makes these part of the debugger information on the
492// closure.
493BeginTest("Closure 3");
494
495function closure_3(a, b) {
496 var x = a + 2;
497 var y = b + 2;
498 function f() {
499 debugger;
500 return a + b + x + y;
501 };
502 return f;
503}
504
505listener_delegate = function(exec_state) {
506 CheckScopeChain([debug.ScopeType.Local,
507 debug.ScopeType.Closure,
508 debug.ScopeType.Global], exec_state);
509 CheckScopeContent({a:1,b:2,x:3,y:4}, 1, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000510};
511closure_3(1, 2)();
Steve Blocka7e24c12009-10-30 11:49:00 +0000512EndTest();
513
514
515
516// Simple closure formed by returning an inner function referering the outer
517// functions arguments. Using all arguments and locals from the outer function
518// in the inner function makes these part of the debugger information on the
519// closure. Use the inner function as well...
520BeginTest("Closure 4");
521
522function closure_4(a, b) {
523 var x = a + 2;
524 var y = b + 2;
525 function f() {
526 debugger;
527 if (f) {
528 return a + b + x + y;
529 }
530 };
531 return f;
532}
533
534listener_delegate = function(exec_state) {
535 CheckScopeChain([debug.ScopeType.Local,
536 debug.ScopeType.Closure,
537 debug.ScopeType.Global], exec_state);
538 CheckScopeContent({a:1,b:2,x:3,y:4,f:function(){}}, 1, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000539};
540closure_4(1, 2)();
Steve Blocka7e24c12009-10-30 11:49:00 +0000541EndTest();
542
543
544
545// Simple closure formed by returning an inner function referering the outer
546// functions arguments. In the presence of eval all arguments and locals
547// (including the inner function itself) from the outer function becomes part of
548// the debugger infformation on the closure.
549BeginTest("Closure 5");
550
551function closure_5(a, b) {
552 var x = 3;
553 var y = 4;
554 function f() {
555 eval('');
556 debugger;
557 return 1;
558 };
559 return f;
560}
561
562listener_delegate = function(exec_state) {
563 CheckScopeChain([debug.ScopeType.Local,
564 debug.ScopeType.Closure,
565 debug.ScopeType.Global], exec_state);
566 CheckScopeContent({a:1,b:2,x:3,y:4,f:function(){}}, 1, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000567};
568closure_5(1, 2)();
Steve Blocka7e24c12009-10-30 11:49:00 +0000569EndTest();
570
571
572// Two closures. Due to optimizations only the parts actually used are provided
573// through the debugger information.
574BeginTest("Closure 6");
575function closure_6(a, b) {
576 function f(a, b) {
577 var x = 3;
578 var y = 4;
579 return function() {
580 var x = 3;
581 var y = 4;
582 debugger;
583 some_global = a;
584 return f;
Ben Murdoch257744e2011-11-30 15:57:28 +0000585 };
Steve Blocka7e24c12009-10-30 11:49:00 +0000586 }
587 return f(a, b);
588}
589
590listener_delegate = function(exec_state) {
591 CheckScopeChain([debug.ScopeType.Local,
592 debug.ScopeType.Closure,
593 debug.ScopeType.Closure,
594 debug.ScopeType.Global], exec_state);
595 CheckScopeContent({a:1}, 1, exec_state);
596 CheckScopeContent({f:function(){}}, 2, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000597};
598closure_6(1, 2)();
Steve Blocka7e24c12009-10-30 11:49:00 +0000599EndTest();
600
601
602// Two closures. In the presence of eval all information is provided as the
603// compiler cannot determine which parts are used.
604BeginTest("Closure 7");
605function closure_7(a, b) {
606 var x = 3;
607 var y = 4;
608 eval('var i = 5');
609 eval('var j = 6');
610 function f(a, b) {
611 var x = 3;
612 var y = 4;
613 eval('var i = 5');
614 eval('var j = 6');
615 return function() {
616 debugger;
617 some_global = a;
618 return f;
Ben Murdoch257744e2011-11-30 15:57:28 +0000619 };
Steve Blocka7e24c12009-10-30 11:49:00 +0000620 }
621 return f(a, b);
622}
623
624listener_delegate = function(exec_state) {
625 CheckScopeChain([debug.ScopeType.Local,
626 debug.ScopeType.Closure,
627 debug.ScopeType.Closure,
628 debug.ScopeType.Global], exec_state);
629 CheckScopeContent({}, 0, exec_state);
630 CheckScopeContent({a:1,b:2,x:3,y:4,i:5,j:6}, 1, exec_state);
631 CheckScopeContent({a:1,b:2,x:3,y:4,i:5,j:6,f:function(){}}, 2, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000632};
633closure_7(1, 2)();
Ben Murdoch8b112d22011-06-08 16:22:53 +0100634EndTest();
635
636
637// Closure that may be optimized out.
638BeginTest("Closure 8");
639function closure_8() {
640 (function inner(x) {
641 debugger;
642 })(2);
Steve Blocka7e24c12009-10-30 11:49:00 +0000643}
Ben Murdoch8b112d22011-06-08 16:22:53 +0100644
645listener_delegate = function(exec_state) {
646 CheckScopeChain([debug.ScopeType.Local,
647 debug.ScopeType.Global], exec_state);
648 CheckScopeContent({x: 2}, 0, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000649};
Ben Murdoch8b112d22011-06-08 16:22:53 +0100650closure_8();
651EndTest();
652
653
654BeginTest("Closure 9");
655function closure_9() {
656 eval("var y = 1;");
657 eval("var z = 1;");
658 (function inner(x) {
Ben Murdoch257744e2011-11-30 15:57:28 +0000659 y++;
Ben Murdoch8b112d22011-06-08 16:22:53 +0100660 z++;
661 debugger;
662 })(2);
663}
664
665listener_delegate = function(exec_state) {
666 CheckScopeChain([debug.ScopeType.Local,
667 debug.ScopeType.Closure,
668 debug.ScopeType.Global], exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000669};
Ben Murdoch8b112d22011-06-08 16:22:53 +0100670closure_9();
Steve Blocka7e24c12009-10-30 11:49:00 +0000671EndTest();
672
673
674// Test a mixture of scopes.
675BeginTest("The full monty");
676function the_full_monty(a, b) {
677 var x = 3;
678 var y = 4;
679 eval('var i = 5');
680 eval('var j = 6');
681 function f(a, b) {
682 var x = 9;
683 var y = 10;
684 eval('var i = 11');
685 eval('var j = 12');
686 with ({j:13}){
687 return function() {
688 var x = 14;
Steve Block6ded16b2010-05-10 14:33:55 +0100689 with ({a:15}) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000690 with ({b:16}) {
691 debugger;
692 some_global = a;
693 return f;
694 }
695 }
Ben Murdoch257744e2011-11-30 15:57:28 +0000696 };
Steve Blocka7e24c12009-10-30 11:49:00 +0000697 }
698 }
699 return f(a, b);
700}
701
702listener_delegate = function(exec_state) {
703 CheckScopeChain([debug.ScopeType.With,
704 debug.ScopeType.With,
705 debug.ScopeType.Local,
706 debug.ScopeType.With,
707 debug.ScopeType.Closure,
708 debug.ScopeType.Closure,
709 debug.ScopeType.Global], exec_state);
710 CheckScopeContent({b:16}, 0, exec_state);
711 CheckScopeContent({a:15}, 1, exec_state);
712 CheckScopeContent({x:14}, 2, exec_state);
713 CheckScopeContent({j:13}, 3, exec_state);
714 CheckScopeContent({a:1,b:2,x:9,y:10,i:11,j:12}, 4, exec_state);
715 CheckScopeContent({a:1,b:2,x:3,y:4,i:5,j:6,f:function(){}}, 5, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000716};
717the_full_monty(1, 2)();
Steve Blocka7e24c12009-10-30 11:49:00 +0000718EndTest();
719
Ben Murdoch8b112d22011-06-08 16:22:53 +0100720
721BeginTest("Closure inside With 1");
722function closure_in_with_1() {
723 with({x:1}) {
724 (function inner(x) {
725 debugger;
726 })(2);
727 }
728}
729
730listener_delegate = function(exec_state) {
731 CheckScopeChain([debug.ScopeType.Local,
732 debug.ScopeType.With,
733 debug.ScopeType.Closure,
734 debug.ScopeType.Global], exec_state);
735 CheckScopeContent({x: 2}, 0, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000736};
Ben Murdoch8b112d22011-06-08 16:22:53 +0100737closure_in_with_1();
738EndTest();
739
740
741BeginTest("Closure inside With 2");
742function closure_in_with_2() {
743 with({x:1}) {
744 (function inner(x) {
745 with({x:3}) {
746 debugger;
747 }
748 })(2);
749 }
750}
751
752listener_delegate = function(exec_state) {
753 CheckScopeChain([debug.ScopeType.With,
754 debug.ScopeType.Local,
755 debug.ScopeType.With,
756 debug.ScopeType.Closure,
757 debug.ScopeType.Global], exec_state);
758 CheckScopeContent({x: 3}, 0, exec_state);
759 CheckScopeContent({x: 2}, 1, exec_state);
760 CheckScopeContent({x: 1}, 2, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000761};
Ben Murdoch8b112d22011-06-08 16:22:53 +0100762closure_in_with_2();
763EndTest();
764
765
766BeginTest("Closure inside With 3");
767function createClosure(a) {
768 var b = a + 1;
769 return function closure() {
770 var c = b;
771 (function inner(x) {
772 with({x:c}) {
773 debugger;
774 }
775 })(2);
Ben Murdoch257744e2011-11-30 15:57:28 +0000776 };
Ben Murdoch8b112d22011-06-08 16:22:53 +0100777}
778
779function closure_in_with_3() {
780 var f = createClosure(0);
781 f();
782}
783
784listener_delegate = function(exec_state) {
785 CheckScopeChain([debug.ScopeType.With,
786 debug.ScopeType.Local,
787 debug.ScopeType.Closure,
788 debug.ScopeType.Closure,
789 debug.ScopeType.Global], exec_state);
790}
791closure_in_with_3();
792EndTest();
793
794
Ben Murdoch589d6972011-11-30 16:04:58 +0000795BeginTest("Closure inside With 4");
796listener_delegate = function(exec_state) {
797 CheckScopeChain([debug.ScopeType.Local,
798 debug.ScopeType.With,
799 debug.ScopeType.Global], exec_state);
800 CheckScopeContent({x: 2}, 0, exec_state);
801 CheckScopeContent({x: 1}, 1, exec_state);
802};
803
804with({x:1}) {
805 (function(x) {
806 debugger;
807 })(2);
808}
809EndTest();
810
811
Steve Blocka7e24c12009-10-30 11:49:00 +0000812// Test global scope.
813BeginTest("Global");
814listener_delegate = function(exec_state) {
815 CheckScopeChain([debug.ScopeType.Global], exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000816};
Steve Blocka7e24c12009-10-30 11:49:00 +0000817debugger;
818EndTest();
819
820
821BeginTest("Catch block 1");
822function catch_block_1() {
823 try {
824 throw 'Exception';
825 } catch (e) {
826 debugger;
827 }
828};
829
830
831listener_delegate = function(exec_state) {
832 CheckScopeChain([debug.ScopeType.Catch,
833 debug.ScopeType.Local,
834 debug.ScopeType.Global], exec_state);
835 CheckScopeContent({e:'Exception'}, 0, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000836};
837catch_block_1();
Steve Blocka7e24c12009-10-30 11:49:00 +0000838EndTest();
839
840
841BeginTest("Catch block 2");
842function catch_block_2() {
843 try {
844 throw 'Exception';
845 } catch (e) {
846 with({n:10}) {
847 debugger;
848 }
849 }
850};
851
852
853listener_delegate = function(exec_state) {
854 CheckScopeChain([debug.ScopeType.With,
855 debug.ScopeType.Catch,
856 debug.ScopeType.Local,
857 debug.ScopeType.Global], exec_state);
858 CheckScopeContent({n:10}, 0, exec_state);
859 CheckScopeContent({e:'Exception'}, 1, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000860};
861catch_block_2();
Steve Blocka7e24c12009-10-30 11:49:00 +0000862EndTest();
863
864
865BeginTest("Catch block 3");
Steve Block6ded16b2010-05-10 14:33:55 +0100866function catch_block_3() {
Steve Blocka7e24c12009-10-30 11:49:00 +0000867 // Do eval to dynamically declare a local variable so that the context's
868 // extension slot is initialized with JSContextExtensionObject.
869 eval("var y = 78;");
870 try {
871 throw 'Exception';
872 } catch (e) {
873 debugger;
874 }
875};
876
877
878listener_delegate = function(exec_state) {
879 CheckScopeChain([debug.ScopeType.Catch,
880 debug.ScopeType.Local,
881 debug.ScopeType.Global], exec_state);
882 CheckScopeContent({e:'Exception'}, 0, exec_state);
883 CheckScopeContent({y:78}, 1, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000884};
885catch_block_3();
Steve Blocka7e24c12009-10-30 11:49:00 +0000886EndTest();
887
888
889BeginTest("Catch block 4");
Steve Block6ded16b2010-05-10 14:33:55 +0100890function catch_block_4() {
Steve Blocka7e24c12009-10-30 11:49:00 +0000891 // Do eval to dynamically declare a local variable so that the context's
892 // extension slot is initialized with JSContextExtensionObject.
893 eval("var y = 98;");
894 try {
895 throw 'Exception';
896 } catch (e) {
897 with({n:10}) {
898 debugger;
899 }
900 }
901};
902
903listener_delegate = function(exec_state) {
904 CheckScopeChain([debug.ScopeType.With,
905 debug.ScopeType.Catch,
906 debug.ScopeType.Local,
907 debug.ScopeType.Global], exec_state);
908 CheckScopeContent({n:10}, 0, exec_state);
909 CheckScopeContent({e:'Exception'}, 1, exec_state);
910 CheckScopeContent({y:98}, 2, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000911};
912catch_block_4();
Steve Blocka7e24c12009-10-30 11:49:00 +0000913EndTest();
914
915
Ben Murdoch589d6972011-11-30 16:04:58 +0000916// Test catch in global scope.
917BeginTest("Catch block 5");
918listener_delegate = function(exec_state) {
919 CheckScopeChain([debug.ScopeType.Catch,
920 debug.ScopeType.Global], exec_state);
921 CheckScopeContent({e:'Exception'}, 0, exec_state);
922};
923
924try {
925 throw 'Exception';
926} catch (e) {
927 debugger;
928}
929
930EndTest();
931
932
933// Closure inside catch in global code.
934BeginTest("Catch block 6");
935listener_delegate = function(exec_state) {
936 CheckScopeChain([debug.ScopeType.Local,
937 debug.ScopeType.Catch,
938 debug.ScopeType.Global], exec_state);
939 CheckScopeContent({x: 2}, 0, exec_state);
940 CheckScopeContent({e:'Exception'}, 1, exec_state);
941};
942
943try {
944 throw 'Exception';
945} catch (e) {
946 (function(x) {
947 debugger;
948 })(2);
949}
950EndTest();
951
952
Ben Murdoch257744e2011-11-30 15:57:28 +0000953assertEquals(begin_test_count, break_count,
954 'one or more tests did not enter the debugger');
955assertEquals(begin_test_count, end_test_count,
956 'one or more tests did not have its result checked');