blob: 942bd2bb073804571bf39b01db88b07d25f44479 [file] [log] [blame]
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001// Copyright 2011 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 Murdoch3ef787d2012-04-12 10:51:47 +010028// Flags: --expose-debug-as debug --allow-natives-syntax
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
Steve Blocka7e24c12009-10-30 11:49:00 +000032// Get the Debug object exposed from the debug context global object.
Ben Murdoch3ef787d2012-04-12 10:51:47 +010033var Debug = debug.Debug;
Steve Blocka7e24c12009-10-30 11:49:00 +000034
Ben Murdoch257744e2011-11-30 15:57:28 +000035var test_name;
Steve Blocka7e24c12009-10-30 11:49:00 +000036var listener_delegate;
37var listener_called;
38var exception;
39var begin_test_count = 0;
40var end_test_count = 0;
41var break_count = 0;
42
43
44// Debug event listener which delegates.
45function listener(event, exec_state, event_data, data) {
46 try {
47 if (event == Debug.DebugEvent.Break) {
48 break_count++;
49 listener_called = true;
Ben Murdoch257744e2011-11-30 15:57:28 +000050 listener_delegate(exec_state);
Steve Blocka7e24c12009-10-30 11:49:00 +000051 }
52 } catch (e) {
53 exception = e;
54 }
55}
56
57// Add the debug event listener.
58Debug.setListener(listener);
59
60
Ben Murdoch257744e2011-11-30 15:57:28 +000061// Initialize for a new test.
Steve Blocka7e24c12009-10-30 11:49:00 +000062function BeginTest(name) {
63 test_name = name;
64 listener_delegate = null;
65 listener_called = false;
66 exception = null;
67 begin_test_count++;
68}
69
70
71// Check result of a test.
72function EndTest() {
73 assertTrue(listener_called, "listerner not called for " + test_name);
Ben Murdoch257744e2011-11-30 15:57:28 +000074 assertNull(exception, test_name);
Steve Blocka7e24c12009-10-30 11:49:00 +000075 end_test_count++;
76}
77
78
79// Check that the scope chain contains the expected types of scopes.
80function CheckScopeChain(scopes, exec_state) {
81 assertEquals(scopes.length, exec_state.frame().scopeCount());
82 for (var i = 0; i < scopes.length; i++) {
83 var scope = exec_state.frame().scope(i);
84 assertTrue(scope.isScope());
85 assertEquals(scopes[i], scope.scopeType());
Steve Block6ded16b2010-05-10 14:33:55 +010086
Steve Blocka7e24c12009-10-30 11:49:00 +000087 // Check the global object when hitting the global scope.
88 if (scopes[i] == debug.ScopeType.Global) {
Ben Murdoch257744e2011-11-30 15:57:28 +000089 // Objects don't have same class (one is "global", other is "Object",
90 // so just check the properties directly.
91 assertPropertiesEqual(this, scope.scopeObject().value());
Steve Blocka7e24c12009-10-30 11:49:00 +000092 }
93 }
Steve Block6ded16b2010-05-10 14:33:55 +010094
Steve Blocka7e24c12009-10-30 11:49:00 +000095 // Get the debug command processor.
Steve Block3ce2e202009-11-05 08:53:23 +000096 var dcp = exec_state.debugCommandProcessor("unspecified_running_state");
Steve Block6ded16b2010-05-10 14:33:55 +010097
Steve Blocka7e24c12009-10-30 11:49:00 +000098 // Send a scopes request and check the result.
99 var json;
Ben Murdoch257744e2011-11-30 15:57:28 +0000100 var request_json = '{"seq":0,"type":"request","command":"scopes"}';
Steve Blocka7e24c12009-10-30 11:49:00 +0000101 var response_json = dcp.processDebugJSONRequest(request_json);
102 var response = JSON.parse(response_json);
103 assertEquals(scopes.length, response.body.scopes.length);
104 for (var i = 0; i < scopes.length; i++) {
105 assertEquals(i, response.body.scopes[i].index);
106 assertEquals(scopes[i], response.body.scopes[i].type);
107 if (scopes[i] == debug.ScopeType.Local ||
108 scopes[i] == debug.ScopeType.Closure) {
109 assertTrue(response.body.scopes[i].object.ref < 0);
110 } else {
111 assertTrue(response.body.scopes[i].object.ref >= 0);
112 }
113 var found = false;
114 for (var j = 0; j < response.refs.length && !found; j++) {
115 found = response.refs[j].handle == response.body.scopes[i].object.ref;
116 }
117 assertTrue(found, "Scope object " + response.body.scopes[i].object.ref + " not found");
118 }
119}
120
121
122// Check that the content of the scope is as expected. For functions just check
123// that there is a function.
124function CheckScopeContent(content, number, exec_state) {
Ben Murdoch257744e2011-11-30 15:57:28 +0000125 var scope = exec_state.frame().scope(number);
Steve Blocka7e24c12009-10-30 11:49:00 +0000126 var count = 0;
127 for (var p in content) {
128 var property_mirror = scope.scopeObject().property(p);
129 assertFalse(property_mirror.isUndefined(), 'property ' + p + ' not found in scope');
130 if (typeof(content[p]) === 'function') {
131 assertTrue(property_mirror.value().isFunction());
132 } else {
133 assertEquals(content[p], property_mirror.value().value(), 'property ' + p + ' has unexpected value');
134 }
135 count++;
136 }
Steve Block6ded16b2010-05-10 14:33:55 +0100137
Steve Blocka7e24c12009-10-30 11:49:00 +0000138 // 'arguments' and might be exposed in the local and closure scope. Just
139 // ignore this.
140 var scope_size = scope.scopeObject().properties().length;
141 if (!scope.scopeObject().property('arguments').isUndefined()) {
142 scope_size--;
143 }
144 // Also ignore synthetic variable from catch block.
145 if (!scope.scopeObject().property('.catch-var').isUndefined()) {
146 scope_size--;
147 }
Ben Murdoch8b112d22011-06-08 16:22:53 +0100148 // Skip property with empty name.
149 if (!scope.scopeObject().property('').isUndefined()) {
150 scope_size--;
151 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000152
153 if (count != scope_size) {
154 print('Names found in scope:');
155 var names = scope.scopeObject().propertyNames();
156 for (var i = 0; i < names.length; i++) {
157 print(names[i]);
158 }
159 }
160 assertEquals(count, scope_size);
161
162 // Get the debug command processor.
Steve Block3ce2e202009-11-05 08:53:23 +0000163 var dcp = exec_state.debugCommandProcessor("unspecified_running_state");
Steve Block6ded16b2010-05-10 14:33:55 +0100164
Steve Blocka7e24c12009-10-30 11:49:00 +0000165 // Send a scope request for information on a single scope and check the
166 // result.
Ben Murdoch257744e2011-11-30 15:57:28 +0000167 var request_json = '{"seq":0,"type":"request","command":"scope","arguments":{"number":';
Steve Blocka7e24c12009-10-30 11:49:00 +0000168 request_json += scope.scopeIndex();
Ben Murdoch257744e2011-11-30 15:57:28 +0000169 request_json += '}}';
Steve Blocka7e24c12009-10-30 11:49:00 +0000170 var response_json = dcp.processDebugJSONRequest(request_json);
171 var response = JSON.parse(response_json);
172 assertEquals(scope.scopeType(), response.body.type);
173 assertEquals(number, response.body.index);
174 if (scope.scopeType() == debug.ScopeType.Local ||
175 scope.scopeType() == debug.ScopeType.Closure) {
176 assertTrue(response.body.object.ref < 0);
177 } else {
178 assertTrue(response.body.object.ref >= 0);
179 }
180 var found = false;
181 for (var i = 0; i < response.refs.length && !found; i++) {
182 found = response.refs[i].handle == response.body.object.ref;
183 }
184 assertTrue(found, "Scope object " + response.body.object.ref + " not found");
185}
186
187
188// Simple empty local scope.
189BeginTest("Local 1");
190
191function local_1() {
192 debugger;
193}
194
195listener_delegate = function(exec_state) {
196 CheckScopeChain([debug.ScopeType.Local,
197 debug.ScopeType.Global], exec_state);
198 CheckScopeContent({}, 0, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000199};
200local_1();
Steve Blocka7e24c12009-10-30 11:49:00 +0000201EndTest();
202
203
204// Local scope with a parameter.
205BeginTest("Local 2");
206
207function local_2(a) {
208 debugger;
209}
210
211listener_delegate = function(exec_state) {
212 CheckScopeChain([debug.ScopeType.Local,
213 debug.ScopeType.Global], exec_state);
214 CheckScopeContent({a:1}, 0, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000215};
216local_2(1);
Steve Blocka7e24c12009-10-30 11:49:00 +0000217EndTest();
218
219
220// Local scope with a parameter and a local variable.
221BeginTest("Local 3");
222
223function local_3(a) {
224 var x = 3;
225 debugger;
226}
227
228listener_delegate = function(exec_state) {
229 CheckScopeChain([debug.ScopeType.Local,
230 debug.ScopeType.Global], exec_state);
231 CheckScopeContent({a:1,x:3}, 0, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000232};
233local_3(1);
Steve Blocka7e24c12009-10-30 11:49:00 +0000234EndTest();
235
236
237// Local scope with parameters and local variables.
238BeginTest("Local 4");
239
240function local_4(a, b) {
241 var x = 3;
242 var y = 4;
243 debugger;
244}
245
246listener_delegate = function(exec_state) {
247 CheckScopeChain([debug.ScopeType.Local,
248 debug.ScopeType.Global], exec_state);
249 CheckScopeContent({a:1,b:2,x:3,y:4}, 0, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000250};
251local_4(1, 2);
Steve Blocka7e24c12009-10-30 11:49:00 +0000252EndTest();
253
254
255// Empty local scope with use of eval.
256BeginTest("Local 5");
257
258function local_5() {
259 eval('');
260 debugger;
261}
262
263listener_delegate = function(exec_state) {
264 CheckScopeChain([debug.ScopeType.Local,
265 debug.ScopeType.Global], exec_state);
266 CheckScopeContent({}, 0, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000267};
268local_5();
Steve Blocka7e24c12009-10-30 11:49:00 +0000269EndTest();
270
271
272// Local introducing local variable using eval.
273BeginTest("Local 6");
274
275function local_6() {
276 eval('var i = 5');
277 debugger;
278}
279
280listener_delegate = function(exec_state) {
281 CheckScopeChain([debug.ScopeType.Local,
282 debug.ScopeType.Global], exec_state);
283 CheckScopeContent({i:5}, 0, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000284};
285local_6();
Steve Blocka7e24c12009-10-30 11:49:00 +0000286EndTest();
287
288
289// Local scope with parameters, local variables and local variable introduced
290// using eval.
291BeginTest("Local 7");
292
293function local_7(a, b) {
294 var x = 3;
295 var y = 4;
296 eval('var i = 5');
297 eval('var j = 6');
298 debugger;
299}
300
301listener_delegate = function(exec_state) {
302 CheckScopeChain([debug.ScopeType.Local,
303 debug.ScopeType.Global], exec_state);
304 CheckScopeContent({a:1,b:2,x:3,y:4,i:5,j:6}, 0, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000305};
306local_7(1, 2);
Steve Blocka7e24c12009-10-30 11:49:00 +0000307EndTest();
308
309
310// Single empty with block.
311BeginTest("With 1");
312
313function with_1() {
314 with({}) {
315 debugger;
316 }
317}
318
319listener_delegate = function(exec_state) {
320 CheckScopeChain([debug.ScopeType.With,
321 debug.ScopeType.Local,
322 debug.ScopeType.Global], exec_state);
323 CheckScopeContent({}, 0, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000324};
325with_1();
Steve Blocka7e24c12009-10-30 11:49:00 +0000326EndTest();
327
328
329// Nested empty with blocks.
330BeginTest("With 2");
331
332function with_2() {
333 with({}) {
334 with({}) {
335 debugger;
336 }
337 }
338}
339
340listener_delegate = function(exec_state) {
341 CheckScopeChain([debug.ScopeType.With,
342 debug.ScopeType.With,
343 debug.ScopeType.Local,
344 debug.ScopeType.Global], exec_state);
345 CheckScopeContent({}, 0, exec_state);
346 CheckScopeContent({}, 1, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000347};
348with_2();
Steve Blocka7e24c12009-10-30 11:49:00 +0000349EndTest();
350
351
352// With block using an in-place object literal.
353BeginTest("With 3");
354
355function with_3() {
356 with({a:1,b:2}) {
357 debugger;
358 }
359}
360
361listener_delegate = function(exec_state) {
362 CheckScopeChain([debug.ScopeType.With,
363 debug.ScopeType.Local,
364 debug.ScopeType.Global], exec_state);
365 CheckScopeContent({a:1,b:2}, 0, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000366};
367with_3();
Steve Blocka7e24c12009-10-30 11:49:00 +0000368EndTest();
369
370
371// Nested with blocks using in-place object literals.
372BeginTest("With 4");
373
374function with_4() {
375 with({a:1,b:2}) {
376 with({a:2,b:1}) {
377 debugger;
378 }
379 }
380}
381
382listener_delegate = function(exec_state) {
383 CheckScopeChain([debug.ScopeType.With,
384 debug.ScopeType.With,
385 debug.ScopeType.Local,
386 debug.ScopeType.Global], exec_state);
387 CheckScopeContent({a:2,b:1}, 0, exec_state);
388 CheckScopeContent({a:1,b:2}, 1, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000389};
390with_4();
Steve Blocka7e24c12009-10-30 11:49:00 +0000391EndTest();
392
393
394// Nested with blocks using existing object.
395BeginTest("With 5");
396
397var with_object = {c:3,d:4};
398function with_5() {
399 with(with_object) {
400 with(with_object) {
401 debugger;
402 }
403 }
404}
405
406listener_delegate = function(exec_state) {
407 CheckScopeChain([debug.ScopeType.With,
408 debug.ScopeType.With,
409 debug.ScopeType.Local,
410 debug.ScopeType.Global], exec_state);
411 CheckScopeContent(with_object, 0, exec_state);
412 CheckScopeContent(with_object, 1, exec_state);
413 assertEquals(exec_state.frame().scope(0).scopeObject(), exec_state.frame().scope(1).scopeObject());
414 assertEquals(with_object, exec_state.frame().scope(1).scopeObject().value());
Ben Murdoch257744e2011-11-30 15:57:28 +0000415};
416with_5();
Steve Blocka7e24c12009-10-30 11:49:00 +0000417EndTest();
418
419
Ben Murdoch589d6972011-11-30 16:04:58 +0000420// Nested with blocks using existing object in global code.
421BeginTest("With 6");
422listener_delegate = function(exec_state) {
423 CheckScopeChain([debug.ScopeType.With,
424 debug.ScopeType.With,
425 debug.ScopeType.Global], exec_state);
426 CheckScopeContent(with_object, 0, exec_state);
427 CheckScopeContent(with_object, 1, exec_state);
428 assertEquals(exec_state.frame().scope(0).scopeObject(), exec_state.frame().scope(1).scopeObject());
429 assertEquals(with_object, exec_state.frame().scope(1).scopeObject().value());
430};
431
432var with_object = {c:3,d:4};
433with(with_object) {
434 with(with_object) {
435 debugger;
436 }
437}
438EndTest();
439
440
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100441// With block in function that is marked for optimization while being executed.
442BeginTest("With 7");
443
444function with_7() {
445 with({}) {
446 %OptimizeFunctionOnNextCall(with_7);
447 debugger;
448 }
449}
450
451listener_delegate = function(exec_state) {
452 CheckScopeChain([debug.ScopeType.With,
453 debug.ScopeType.Local,
454 debug.ScopeType.Global], exec_state);
455 CheckScopeContent({}, 0, exec_state);
456};
457with_7();
458EndTest();
459
460
Steve Blocka7e24c12009-10-30 11:49:00 +0000461// Simple closure formed by returning an inner function referering the outer
462// functions arguments.
463BeginTest("Closure 1");
464
465function closure_1(a) {
466 function f() {
467 debugger;
468 return a;
469 };
470 return f;
471}
472
473listener_delegate = function(exec_state) {
474 CheckScopeChain([debug.ScopeType.Local,
475 debug.ScopeType.Closure,
476 debug.ScopeType.Global], exec_state);
477 CheckScopeContent({a:1}, 1, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000478};
479closure_1(1)();
Steve Blocka7e24c12009-10-30 11:49:00 +0000480EndTest();
481
482
483// Simple closure formed by returning an inner function referering the outer
484// functions arguments. Due to VM optimizations parts of the actual closure is
485// missing from the debugger information.
486BeginTest("Closure 2");
487
488function closure_2(a, b) {
489 var x = a + 2;
490 var y = b + 2;
491 function f() {
492 debugger;
493 return a + x;
494 };
495 return f;
496}
497
498listener_delegate = function(exec_state) {
499 CheckScopeChain([debug.ScopeType.Local,
500 debug.ScopeType.Closure,
501 debug.ScopeType.Global], exec_state);
502 CheckScopeContent({a:1,x:3}, 1, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000503};
504closure_2(1, 2)();
Steve Blocka7e24c12009-10-30 11:49:00 +0000505EndTest();
506
507
508// Simple closure formed by returning an inner function referering the outer
509// functions arguments. Using all arguments and locals from the outer function
510// in the inner function makes these part of the debugger information on the
511// closure.
512BeginTest("Closure 3");
513
514function closure_3(a, b) {
515 var x = a + 2;
516 var y = b + 2;
517 function f() {
518 debugger;
519 return a + b + x + y;
520 };
521 return f;
522}
523
524listener_delegate = function(exec_state) {
525 CheckScopeChain([debug.ScopeType.Local,
526 debug.ScopeType.Closure,
527 debug.ScopeType.Global], exec_state);
528 CheckScopeContent({a:1,b:2,x:3,y:4}, 1, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000529};
530closure_3(1, 2)();
Steve Blocka7e24c12009-10-30 11:49:00 +0000531EndTest();
532
533
534
535// Simple closure formed by returning an inner function referering the outer
536// functions arguments. Using all arguments and locals from the outer function
537// in the inner function makes these part of the debugger information on the
538// closure. Use the inner function as well...
539BeginTest("Closure 4");
540
541function closure_4(a, b) {
542 var x = a + 2;
543 var y = b + 2;
544 function f() {
545 debugger;
546 if (f) {
547 return a + b + x + y;
548 }
549 };
550 return f;
551}
552
553listener_delegate = function(exec_state) {
554 CheckScopeChain([debug.ScopeType.Local,
555 debug.ScopeType.Closure,
556 debug.ScopeType.Global], exec_state);
557 CheckScopeContent({a:1,b:2,x:3,y:4,f:function(){}}, 1, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000558};
559closure_4(1, 2)();
Steve Blocka7e24c12009-10-30 11:49:00 +0000560EndTest();
561
562
563
564// Simple closure formed by returning an inner function referering the outer
565// functions arguments. In the presence of eval all arguments and locals
566// (including the inner function itself) from the outer function becomes part of
567// the debugger infformation on the closure.
568BeginTest("Closure 5");
569
570function closure_5(a, b) {
571 var x = 3;
572 var y = 4;
573 function f() {
574 eval('');
575 debugger;
576 return 1;
577 };
578 return f;
579}
580
581listener_delegate = function(exec_state) {
582 CheckScopeChain([debug.ScopeType.Local,
583 debug.ScopeType.Closure,
584 debug.ScopeType.Global], exec_state);
585 CheckScopeContent({a:1,b:2,x:3,y:4,f:function(){}}, 1, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000586};
587closure_5(1, 2)();
Steve Blocka7e24c12009-10-30 11:49:00 +0000588EndTest();
589
590
591// Two closures. Due to optimizations only the parts actually used are provided
592// through the debugger information.
593BeginTest("Closure 6");
594function closure_6(a, b) {
595 function f(a, b) {
596 var x = 3;
597 var y = 4;
598 return function() {
599 var x = 3;
600 var y = 4;
601 debugger;
602 some_global = a;
603 return f;
Ben Murdoch257744e2011-11-30 15:57:28 +0000604 };
Steve Blocka7e24c12009-10-30 11:49:00 +0000605 }
606 return f(a, b);
607}
608
609listener_delegate = function(exec_state) {
610 CheckScopeChain([debug.ScopeType.Local,
611 debug.ScopeType.Closure,
612 debug.ScopeType.Closure,
613 debug.ScopeType.Global], exec_state);
614 CheckScopeContent({a:1}, 1, exec_state);
615 CheckScopeContent({f:function(){}}, 2, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000616};
617closure_6(1, 2)();
Steve Blocka7e24c12009-10-30 11:49:00 +0000618EndTest();
619
620
621// Two closures. In the presence of eval all information is provided as the
622// compiler cannot determine which parts are used.
623BeginTest("Closure 7");
624function closure_7(a, b) {
625 var x = 3;
626 var y = 4;
627 eval('var i = 5');
628 eval('var j = 6');
629 function f(a, b) {
630 var x = 3;
631 var y = 4;
632 eval('var i = 5');
633 eval('var j = 6');
634 return function() {
635 debugger;
636 some_global = a;
637 return f;
Ben Murdoch257744e2011-11-30 15:57:28 +0000638 };
Steve Blocka7e24c12009-10-30 11:49:00 +0000639 }
640 return f(a, b);
641}
642
643listener_delegate = function(exec_state) {
644 CheckScopeChain([debug.ScopeType.Local,
645 debug.ScopeType.Closure,
646 debug.ScopeType.Closure,
647 debug.ScopeType.Global], exec_state);
648 CheckScopeContent({}, 0, exec_state);
649 CheckScopeContent({a:1,b:2,x:3,y:4,i:5,j:6}, 1, exec_state);
650 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 +0000651};
652closure_7(1, 2)();
Ben Murdoch8b112d22011-06-08 16:22:53 +0100653EndTest();
654
655
656// Closure that may be optimized out.
657BeginTest("Closure 8");
658function closure_8() {
659 (function inner(x) {
660 debugger;
661 })(2);
Steve Blocka7e24c12009-10-30 11:49:00 +0000662}
Ben Murdoch8b112d22011-06-08 16:22:53 +0100663
664listener_delegate = function(exec_state) {
665 CheckScopeChain([debug.ScopeType.Local,
666 debug.ScopeType.Global], exec_state);
667 CheckScopeContent({x: 2}, 0, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000668};
Ben Murdoch8b112d22011-06-08 16:22:53 +0100669closure_8();
670EndTest();
671
672
673BeginTest("Closure 9");
674function closure_9() {
675 eval("var y = 1;");
676 eval("var z = 1;");
677 (function inner(x) {
Ben Murdoch257744e2011-11-30 15:57:28 +0000678 y++;
Ben Murdoch8b112d22011-06-08 16:22:53 +0100679 z++;
680 debugger;
681 })(2);
682}
683
684listener_delegate = function(exec_state) {
685 CheckScopeChain([debug.ScopeType.Local,
686 debug.ScopeType.Closure,
687 debug.ScopeType.Global], exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000688};
Ben Murdoch8b112d22011-06-08 16:22:53 +0100689closure_9();
Steve Blocka7e24c12009-10-30 11:49:00 +0000690EndTest();
691
692
693// Test a mixture of scopes.
694BeginTest("The full monty");
695function the_full_monty(a, b) {
696 var x = 3;
697 var y = 4;
698 eval('var i = 5');
699 eval('var j = 6');
700 function f(a, b) {
701 var x = 9;
702 var y = 10;
703 eval('var i = 11');
704 eval('var j = 12');
705 with ({j:13}){
706 return function() {
707 var x = 14;
Steve Block6ded16b2010-05-10 14:33:55 +0100708 with ({a:15}) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000709 with ({b:16}) {
710 debugger;
711 some_global = a;
712 return f;
713 }
714 }
Ben Murdoch257744e2011-11-30 15:57:28 +0000715 };
Steve Blocka7e24c12009-10-30 11:49:00 +0000716 }
717 }
718 return f(a, b);
719}
720
721listener_delegate = function(exec_state) {
722 CheckScopeChain([debug.ScopeType.With,
723 debug.ScopeType.With,
724 debug.ScopeType.Local,
725 debug.ScopeType.With,
726 debug.ScopeType.Closure,
727 debug.ScopeType.Closure,
728 debug.ScopeType.Global], exec_state);
729 CheckScopeContent({b:16}, 0, exec_state);
730 CheckScopeContent({a:15}, 1, exec_state);
731 CheckScopeContent({x:14}, 2, exec_state);
732 CheckScopeContent({j:13}, 3, exec_state);
733 CheckScopeContent({a:1,b:2,x:9,y:10,i:11,j:12}, 4, exec_state);
734 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 +0000735};
736the_full_monty(1, 2)();
Steve Blocka7e24c12009-10-30 11:49:00 +0000737EndTest();
738
Ben Murdoch8b112d22011-06-08 16:22:53 +0100739
740BeginTest("Closure inside With 1");
741function closure_in_with_1() {
742 with({x:1}) {
743 (function inner(x) {
744 debugger;
745 })(2);
746 }
747}
748
749listener_delegate = function(exec_state) {
750 CheckScopeChain([debug.ScopeType.Local,
751 debug.ScopeType.With,
752 debug.ScopeType.Closure,
753 debug.ScopeType.Global], exec_state);
754 CheckScopeContent({x: 2}, 0, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000755};
Ben Murdoch8b112d22011-06-08 16:22:53 +0100756closure_in_with_1();
757EndTest();
758
759
760BeginTest("Closure inside With 2");
761function closure_in_with_2() {
762 with({x:1}) {
763 (function inner(x) {
764 with({x:3}) {
765 debugger;
766 }
767 })(2);
768 }
769}
770
771listener_delegate = function(exec_state) {
772 CheckScopeChain([debug.ScopeType.With,
773 debug.ScopeType.Local,
774 debug.ScopeType.With,
775 debug.ScopeType.Closure,
776 debug.ScopeType.Global], exec_state);
777 CheckScopeContent({x: 3}, 0, exec_state);
778 CheckScopeContent({x: 2}, 1, exec_state);
779 CheckScopeContent({x: 1}, 2, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000780};
Ben Murdoch8b112d22011-06-08 16:22:53 +0100781closure_in_with_2();
782EndTest();
783
784
785BeginTest("Closure inside With 3");
786function createClosure(a) {
787 var b = a + 1;
788 return function closure() {
789 var c = b;
790 (function inner(x) {
791 with({x:c}) {
792 debugger;
793 }
794 })(2);
Ben Murdoch257744e2011-11-30 15:57:28 +0000795 };
Ben Murdoch8b112d22011-06-08 16:22:53 +0100796}
797
798function closure_in_with_3() {
799 var f = createClosure(0);
800 f();
801}
802
803listener_delegate = function(exec_state) {
804 CheckScopeChain([debug.ScopeType.With,
805 debug.ScopeType.Local,
806 debug.ScopeType.Closure,
807 debug.ScopeType.Closure,
808 debug.ScopeType.Global], exec_state);
809}
810closure_in_with_3();
811EndTest();
812
813
Ben Murdoch589d6972011-11-30 16:04:58 +0000814BeginTest("Closure inside With 4");
815listener_delegate = function(exec_state) {
816 CheckScopeChain([debug.ScopeType.Local,
817 debug.ScopeType.With,
818 debug.ScopeType.Global], exec_state);
819 CheckScopeContent({x: 2}, 0, exec_state);
820 CheckScopeContent({x: 1}, 1, exec_state);
821};
822
823with({x:1}) {
824 (function(x) {
825 debugger;
826 })(2);
827}
828EndTest();
829
830
Steve Blocka7e24c12009-10-30 11:49:00 +0000831// Test global scope.
832BeginTest("Global");
833listener_delegate = function(exec_state) {
834 CheckScopeChain([debug.ScopeType.Global], exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000835};
Steve Blocka7e24c12009-10-30 11:49:00 +0000836debugger;
837EndTest();
838
839
840BeginTest("Catch block 1");
841function catch_block_1() {
842 try {
843 throw 'Exception';
844 } catch (e) {
845 debugger;
846 }
847};
848
849
850listener_delegate = function(exec_state) {
851 CheckScopeChain([debug.ScopeType.Catch,
852 debug.ScopeType.Local,
853 debug.ScopeType.Global], exec_state);
854 CheckScopeContent({e:'Exception'}, 0, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000855};
856catch_block_1();
Steve Blocka7e24c12009-10-30 11:49:00 +0000857EndTest();
858
859
860BeginTest("Catch block 2");
861function catch_block_2() {
862 try {
863 throw 'Exception';
864 } catch (e) {
865 with({n:10}) {
866 debugger;
867 }
868 }
869};
870
871
872listener_delegate = function(exec_state) {
873 CheckScopeChain([debug.ScopeType.With,
874 debug.ScopeType.Catch,
875 debug.ScopeType.Local,
876 debug.ScopeType.Global], exec_state);
877 CheckScopeContent({n:10}, 0, exec_state);
878 CheckScopeContent({e:'Exception'}, 1, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000879};
880catch_block_2();
Steve Blocka7e24c12009-10-30 11:49:00 +0000881EndTest();
882
883
884BeginTest("Catch block 3");
Steve Block6ded16b2010-05-10 14:33:55 +0100885function catch_block_3() {
Steve Blocka7e24c12009-10-30 11:49:00 +0000886 // Do eval to dynamically declare a local variable so that the context's
887 // extension slot is initialized with JSContextExtensionObject.
888 eval("var y = 78;");
889 try {
890 throw 'Exception';
891 } catch (e) {
892 debugger;
893 }
894};
895
896
897listener_delegate = function(exec_state) {
898 CheckScopeChain([debug.ScopeType.Catch,
899 debug.ScopeType.Local,
900 debug.ScopeType.Global], exec_state);
901 CheckScopeContent({e:'Exception'}, 0, exec_state);
902 CheckScopeContent({y:78}, 1, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000903};
904catch_block_3();
Steve Blocka7e24c12009-10-30 11:49:00 +0000905EndTest();
906
907
908BeginTest("Catch block 4");
Steve Block6ded16b2010-05-10 14:33:55 +0100909function catch_block_4() {
Steve Blocka7e24c12009-10-30 11:49:00 +0000910 // Do eval to dynamically declare a local variable so that the context's
911 // extension slot is initialized with JSContextExtensionObject.
912 eval("var y = 98;");
913 try {
914 throw 'Exception';
915 } catch (e) {
916 with({n:10}) {
917 debugger;
918 }
919 }
920};
921
922listener_delegate = function(exec_state) {
923 CheckScopeChain([debug.ScopeType.With,
924 debug.ScopeType.Catch,
925 debug.ScopeType.Local,
926 debug.ScopeType.Global], exec_state);
927 CheckScopeContent({n:10}, 0, exec_state);
928 CheckScopeContent({e:'Exception'}, 1, exec_state);
929 CheckScopeContent({y:98}, 2, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000930};
931catch_block_4();
Steve Blocka7e24c12009-10-30 11:49:00 +0000932EndTest();
933
934
Ben Murdoch589d6972011-11-30 16:04:58 +0000935// Test catch in global scope.
936BeginTest("Catch block 5");
937listener_delegate = function(exec_state) {
938 CheckScopeChain([debug.ScopeType.Catch,
939 debug.ScopeType.Global], exec_state);
940 CheckScopeContent({e:'Exception'}, 0, exec_state);
941};
942
943try {
944 throw 'Exception';
945} catch (e) {
946 debugger;
947}
948
949EndTest();
950
951
952// Closure inside catch in global code.
953BeginTest("Catch block 6");
954listener_delegate = function(exec_state) {
955 CheckScopeChain([debug.ScopeType.Local,
956 debug.ScopeType.Catch,
957 debug.ScopeType.Global], exec_state);
958 CheckScopeContent({x: 2}, 0, exec_state);
959 CheckScopeContent({e:'Exception'}, 1, exec_state);
960};
961
962try {
963 throw 'Exception';
964} catch (e) {
965 (function(x) {
966 debugger;
967 })(2);
968}
969EndTest();
970
971
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100972// Catch block in function that is marked for optimization while being executed.
973BeginTest("Catch block 7");
974function catch_block_7() {
975 %OptimizeFunctionOnNextCall(catch_block_7);
976 try {
977 throw 'Exception';
978 } catch (e) {
979 debugger;
980 }
981};
982
983
984listener_delegate = function(exec_state) {
985 CheckScopeChain([debug.ScopeType.Catch,
986 debug.ScopeType.Local,
987 debug.ScopeType.Global], exec_state);
988 CheckScopeContent({e:'Exception'}, 0, exec_state);
989};
990catch_block_7();
991EndTest();
992
993
Ben Murdoch257744e2011-11-30 15:57:28 +0000994assertEquals(begin_test_count, break_count,
995 'one or more tests did not enter the debugger');
996assertEquals(begin_test_count, end_test_count,
997 'one or more tests did not have its result checked');