blob: 4823496e3c921ccc48654b4cea0c0b33d11f8b52 [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 Murdochb8a8cc12014-11-26 15:28:44 +000028// Flags: --expose-debug-as debug --allow-natives-syntax --turbo-deoptimization
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 Murdochb8a8cc12014-11-26 15:28:44 +000074 assertNull(exception, test_name + " / " + exception);
Steve Blocka7e24c12009-10-30 11:49:00 +000075 end_test_count++;
76}
77
78
Ben Murdochb8a8cc12014-11-26 15:28:44 +000079// Check that two scope are the same.
80function assertScopeMirrorEquals(scope1, scope2) {
81 assertEquals(scope1.scopeType(), scope2.scopeType());
82 assertEquals(scope1.frameIndex(), scope2.frameIndex());
83 assertEquals(scope1.scopeIndex(), scope2.scopeIndex());
84 assertPropertiesEqual(scope1.scopeObject().value(), scope2.scopeObject().value());
85}
86
87function CheckFastAllScopes(scopes, exec_state)
88{
89 var fast_all_scopes = exec_state.frame().allScopes(true);
90 var length = fast_all_scopes.length;
91 assertTrue(scopes.length >= length);
92 for (var i = 0; i < scopes.length && i < length; i++) {
93 var scope = fast_all_scopes[length - i - 1];
94 assertTrue(scope.isScope());
95 assertEquals(scopes[scopes.length - i - 1], scope.scopeType());
96 }
97}
98
99
Steve Blocka7e24c12009-10-30 11:49:00 +0000100// Check that the scope chain contains the expected types of scopes.
101function CheckScopeChain(scopes, exec_state) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000102 var all_scopes = exec_state.frame().allScopes();
Steve Blocka7e24c12009-10-30 11:49:00 +0000103 assertEquals(scopes.length, exec_state.frame().scopeCount());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000104 assertEquals(scopes.length, all_scopes.length, "FrameMirror.allScopes length");
Steve Blocka7e24c12009-10-30 11:49:00 +0000105 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());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000109 assertScopeMirrorEquals(all_scopes[i], scope);
Steve Block6ded16b2010-05-10 14:33:55 +0100110
Steve Blocka7e24c12009-10-30 11:49:00 +0000111 // Check the global object when hitting the global scope.
112 if (scopes[i] == debug.ScopeType.Global) {
Ben Murdoch257744e2011-11-30 15:57:28 +0000113 // 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());
Steve Blocka7e24c12009-10-30 11:49:00 +0000116 }
117 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000118 CheckFastAllScopes(scopes, exec_state);
Steve Block6ded16b2010-05-10 14:33:55 +0100119
Steve Blocka7e24c12009-10-30 11:49:00 +0000120 // Get the debug command processor.
Steve Block3ce2e202009-11-05 08:53:23 +0000121 var dcp = exec_state.debugCommandProcessor("unspecified_running_state");
Steve Block6ded16b2010-05-10 14:33:55 +0100122
Steve Blocka7e24c12009-10-30 11:49:00 +0000123 // Send a scopes request and check the result.
124 var json;
Ben Murdoch257744e2011-11-30 15:57:28 +0000125 var request_json = '{"seq":0,"type":"request","command":"scopes"}';
Steve Blocka7e24c12009-10-30 11:49:00 +0000126 var response_json = dcp.processDebugJSONRequest(request_json);
127 var response = JSON.parse(response_json);
128 assertEquals(scopes.length, response.body.scopes.length);
129 for (var i = 0; i < scopes.length; i++) {
130 assertEquals(i, response.body.scopes[i].index);
131 assertEquals(scopes[i], response.body.scopes[i].type);
132 if (scopes[i] == debug.ScopeType.Local ||
133 scopes[i] == debug.ScopeType.Closure) {
134 assertTrue(response.body.scopes[i].object.ref < 0);
135 } else {
136 assertTrue(response.body.scopes[i].object.ref >= 0);
137 }
138 var found = false;
139 for (var j = 0; j < response.refs.length && !found; j++) {
140 found = response.refs[j].handle == response.body.scopes[i].object.ref;
141 }
142 assertTrue(found, "Scope object " + response.body.scopes[i].object.ref + " not found");
143 }
144}
145
146
147// Check that the content of the scope is as expected. For functions just check
148// that there is a function.
149function CheckScopeContent(content, number, exec_state) {
Ben Murdoch257744e2011-11-30 15:57:28 +0000150 var scope = exec_state.frame().scope(number);
Steve Blocka7e24c12009-10-30 11:49:00 +0000151 var count = 0;
152 for (var p in content) {
153 var property_mirror = scope.scopeObject().property(p);
154 assertFalse(property_mirror.isUndefined(), 'property ' + p + ' not found in scope');
155 if (typeof(content[p]) === 'function') {
156 assertTrue(property_mirror.value().isFunction());
157 } else {
158 assertEquals(content[p], property_mirror.value().value(), 'property ' + p + ' has unexpected value');
159 }
160 count++;
161 }
Steve Block6ded16b2010-05-10 14:33:55 +0100162
Steve Blocka7e24c12009-10-30 11:49:00 +0000163 // 'arguments' and might be exposed in the local and closure scope. Just
164 // ignore this.
165 var scope_size = scope.scopeObject().properties().length;
166 if (!scope.scopeObject().property('arguments').isUndefined()) {
167 scope_size--;
168 }
Ben Murdoch8b112d22011-06-08 16:22:53 +0100169 // Skip property with empty name.
170 if (!scope.scopeObject().property('').isUndefined()) {
171 scope_size--;
172 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000173
174 if (count != scope_size) {
175 print('Names found in scope:');
176 var names = scope.scopeObject().propertyNames();
177 for (var i = 0; i < names.length; i++) {
178 print(names[i]);
179 }
180 }
181 assertEquals(count, scope_size);
182
183 // Get the debug command processor.
Steve Block3ce2e202009-11-05 08:53:23 +0000184 var dcp = exec_state.debugCommandProcessor("unspecified_running_state");
Steve Block6ded16b2010-05-10 14:33:55 +0100185
Steve Blocka7e24c12009-10-30 11:49:00 +0000186 // Send a scope request for information on a single scope and check the
187 // result.
Ben Murdoch257744e2011-11-30 15:57:28 +0000188 var request_json = '{"seq":0,"type":"request","command":"scope","arguments":{"number":';
Steve Blocka7e24c12009-10-30 11:49:00 +0000189 request_json += scope.scopeIndex();
Ben Murdoch257744e2011-11-30 15:57:28 +0000190 request_json += '}}';
Steve Blocka7e24c12009-10-30 11:49:00 +0000191 var response_json = dcp.processDebugJSONRequest(request_json);
192 var response = JSON.parse(response_json);
193 assertEquals(scope.scopeType(), response.body.type);
194 assertEquals(number, response.body.index);
195 if (scope.scopeType() == debug.ScopeType.Local ||
196 scope.scopeType() == debug.ScopeType.Closure) {
197 assertTrue(response.body.object.ref < 0);
198 } else {
199 assertTrue(response.body.object.ref >= 0);
200 }
201 var found = false;
202 for (var i = 0; i < response.refs.length && !found; i++) {
203 found = response.refs[i].handle == response.body.object.ref;
204 }
205 assertTrue(found, "Scope object " + response.body.object.ref + " not found");
206}
207
208
209// Simple empty local scope.
210BeginTest("Local 1");
211
212function local_1() {
213 debugger;
214}
215
216listener_delegate = function(exec_state) {
217 CheckScopeChain([debug.ScopeType.Local,
218 debug.ScopeType.Global], exec_state);
219 CheckScopeContent({}, 0, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000220};
221local_1();
Steve Blocka7e24c12009-10-30 11:49:00 +0000222EndTest();
223
224
225// Local scope with a parameter.
226BeginTest("Local 2");
227
228function local_2(a) {
229 debugger;
230}
231
232listener_delegate = function(exec_state) {
233 CheckScopeChain([debug.ScopeType.Local,
234 debug.ScopeType.Global], exec_state);
235 CheckScopeContent({a:1}, 0, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000236};
237local_2(1);
Steve Blocka7e24c12009-10-30 11:49:00 +0000238EndTest();
239
240
241// Local scope with a parameter and a local variable.
242BeginTest("Local 3");
243
244function local_3(a) {
245 var x = 3;
246 debugger;
247}
248
249listener_delegate = function(exec_state) {
250 CheckScopeChain([debug.ScopeType.Local,
251 debug.ScopeType.Global], exec_state);
252 CheckScopeContent({a:1,x:3}, 0, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000253};
254local_3(1);
Steve Blocka7e24c12009-10-30 11:49:00 +0000255EndTest();
256
257
258// Local scope with parameters and local variables.
259BeginTest("Local 4");
260
261function local_4(a, b) {
262 var x = 3;
263 var y = 4;
264 debugger;
265}
266
267listener_delegate = function(exec_state) {
268 CheckScopeChain([debug.ScopeType.Local,
269 debug.ScopeType.Global], exec_state);
270 CheckScopeContent({a:1,b:2,x:3,y:4}, 0, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000271};
272local_4(1, 2);
Steve Blocka7e24c12009-10-30 11:49:00 +0000273EndTest();
274
275
276// Empty local scope with use of eval.
277BeginTest("Local 5");
278
279function local_5() {
280 eval('');
281 debugger;
282}
283
284listener_delegate = function(exec_state) {
285 CheckScopeChain([debug.ScopeType.Local,
286 debug.ScopeType.Global], exec_state);
287 CheckScopeContent({}, 0, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000288};
289local_5();
Steve Blocka7e24c12009-10-30 11:49:00 +0000290EndTest();
291
292
293// Local introducing local variable using eval.
294BeginTest("Local 6");
295
296function local_6() {
297 eval('var i = 5');
298 debugger;
299}
300
301listener_delegate = function(exec_state) {
302 CheckScopeChain([debug.ScopeType.Local,
303 debug.ScopeType.Global], exec_state);
304 CheckScopeContent({i:5}, 0, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000305};
306local_6();
Steve Blocka7e24c12009-10-30 11:49:00 +0000307EndTest();
308
309
310// Local scope with parameters, local variables and local variable introduced
311// using eval.
312BeginTest("Local 7");
313
314function local_7(a, b) {
315 var x = 3;
316 var y = 4;
317 eval('var i = 5');
318 eval('var j = 6');
319 debugger;
320}
321
322listener_delegate = function(exec_state) {
323 CheckScopeChain([debug.ScopeType.Local,
324 debug.ScopeType.Global], exec_state);
325 CheckScopeContent({a:1,b:2,x:3,y:4,i:5,j:6}, 0, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000326};
327local_7(1, 2);
Steve Blocka7e24c12009-10-30 11:49:00 +0000328EndTest();
329
330
331// Single empty with block.
332BeginTest("With 1");
333
334function with_1() {
335 with({}) {
336 debugger;
337 }
338}
339
340listener_delegate = function(exec_state) {
341 CheckScopeChain([debug.ScopeType.With,
342 debug.ScopeType.Local,
343 debug.ScopeType.Global], exec_state);
344 CheckScopeContent({}, 0, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000345};
346with_1();
Steve Blocka7e24c12009-10-30 11:49:00 +0000347EndTest();
348
349
350// Nested empty with blocks.
351BeginTest("With 2");
352
353function with_2() {
354 with({}) {
355 with({}) {
356 debugger;
357 }
358 }
359}
360
361listener_delegate = function(exec_state) {
362 CheckScopeChain([debug.ScopeType.With,
363 debug.ScopeType.With,
364 debug.ScopeType.Local,
365 debug.ScopeType.Global], exec_state);
366 CheckScopeContent({}, 0, exec_state);
367 CheckScopeContent({}, 1, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000368};
369with_2();
Steve Blocka7e24c12009-10-30 11:49:00 +0000370EndTest();
371
372
373// With block using an in-place object literal.
374BeginTest("With 3");
375
376function with_3() {
377 with({a:1,b:2}) {
378 debugger;
379 }
380}
381
382listener_delegate = function(exec_state) {
383 CheckScopeChain([debug.ScopeType.With,
384 debug.ScopeType.Local,
385 debug.ScopeType.Global], exec_state);
386 CheckScopeContent({a:1,b:2}, 0, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000387};
388with_3();
Steve Blocka7e24c12009-10-30 11:49:00 +0000389EndTest();
390
391
392// Nested with blocks using in-place object literals.
393BeginTest("With 4");
394
395function with_4() {
396 with({a:1,b:2}) {
397 with({a:2,b:1}) {
398 debugger;
399 }
400 }
401}
402
403listener_delegate = function(exec_state) {
404 CheckScopeChain([debug.ScopeType.With,
405 debug.ScopeType.With,
406 debug.ScopeType.Local,
407 debug.ScopeType.Global], exec_state);
408 CheckScopeContent({a:2,b:1}, 0, exec_state);
409 CheckScopeContent({a:1,b:2}, 1, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000410};
411with_4();
Steve Blocka7e24c12009-10-30 11:49:00 +0000412EndTest();
413
414
415// Nested with blocks using existing object.
416BeginTest("With 5");
417
418var with_object = {c:3,d:4};
419function with_5() {
420 with(with_object) {
421 with(with_object) {
422 debugger;
423 }
424 }
425}
426
427listener_delegate = function(exec_state) {
428 CheckScopeChain([debug.ScopeType.With,
429 debug.ScopeType.With,
430 debug.ScopeType.Local,
431 debug.ScopeType.Global], exec_state);
432 CheckScopeContent(with_object, 0, exec_state);
433 CheckScopeContent(with_object, 1, exec_state);
434 assertEquals(exec_state.frame().scope(0).scopeObject(), exec_state.frame().scope(1).scopeObject());
435 assertEquals(with_object, exec_state.frame().scope(1).scopeObject().value());
Ben Murdoch257744e2011-11-30 15:57:28 +0000436};
437with_5();
Steve Blocka7e24c12009-10-30 11:49:00 +0000438EndTest();
439
440
Ben Murdoch589d6972011-11-30 16:04:58 +0000441// Nested with blocks using existing object in global code.
442BeginTest("With 6");
443listener_delegate = function(exec_state) {
444 CheckScopeChain([debug.ScopeType.With,
445 debug.ScopeType.With,
446 debug.ScopeType.Global], exec_state);
447 CheckScopeContent(with_object, 0, exec_state);
448 CheckScopeContent(with_object, 1, exec_state);
449 assertEquals(exec_state.frame().scope(0).scopeObject(), exec_state.frame().scope(1).scopeObject());
450 assertEquals(with_object, exec_state.frame().scope(1).scopeObject().value());
451};
452
453var with_object = {c:3,d:4};
454with(with_object) {
455 with(with_object) {
456 debugger;
457 }
458}
459EndTest();
460
461
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100462// With block in function that is marked for optimization while being executed.
463BeginTest("With 7");
464
465function with_7() {
466 with({}) {
467 %OptimizeFunctionOnNextCall(with_7);
468 debugger;
469 }
470}
471
472listener_delegate = function(exec_state) {
473 CheckScopeChain([debug.ScopeType.With,
474 debug.ScopeType.Local,
475 debug.ScopeType.Global], exec_state);
476 CheckScopeContent({}, 0, exec_state);
477};
478with_7();
479EndTest();
480
481
Steve Blocka7e24c12009-10-30 11:49:00 +0000482// Simple closure formed by returning an inner function referering the outer
483// functions arguments.
484BeginTest("Closure 1");
485
486function closure_1(a) {
487 function f() {
488 debugger;
489 return a;
490 };
491 return f;
492}
493
494listener_delegate = function(exec_state) {
495 CheckScopeChain([debug.ScopeType.Local,
496 debug.ScopeType.Closure,
497 debug.ScopeType.Global], exec_state);
498 CheckScopeContent({a:1}, 1, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000499};
500closure_1(1)();
Steve Blocka7e24c12009-10-30 11:49:00 +0000501EndTest();
502
503
504// Simple closure formed by returning an inner function referering the outer
505// functions arguments. Due to VM optimizations parts of the actual closure is
506// missing from the debugger information.
507BeginTest("Closure 2");
508
509function closure_2(a, b) {
510 var x = a + 2;
511 var y = b + 2;
512 function f() {
513 debugger;
514 return a + x;
515 };
516 return f;
517}
518
519listener_delegate = function(exec_state) {
520 CheckScopeChain([debug.ScopeType.Local,
521 debug.ScopeType.Closure,
522 debug.ScopeType.Global], exec_state);
523 CheckScopeContent({a:1,x:3}, 1, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000524};
525closure_2(1, 2)();
Steve Blocka7e24c12009-10-30 11:49:00 +0000526EndTest();
527
528
529// Simple closure formed by returning an inner function referering the outer
530// functions arguments. Using all arguments and locals from the outer function
531// in the inner function makes these part of the debugger information on the
532// closure.
533BeginTest("Closure 3");
534
535function closure_3(a, b) {
536 var x = a + 2;
537 var y = b + 2;
538 function f() {
539 debugger;
540 return a + b + x + y;
541 };
542 return f;
543}
544
545listener_delegate = function(exec_state) {
546 CheckScopeChain([debug.ScopeType.Local,
547 debug.ScopeType.Closure,
548 debug.ScopeType.Global], exec_state);
549 CheckScopeContent({a:1,b:2,x:3,y:4}, 1, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000550};
551closure_3(1, 2)();
Steve Blocka7e24c12009-10-30 11:49:00 +0000552EndTest();
553
554
555
556// Simple closure formed by returning an inner function referering the outer
557// functions arguments. Using all arguments and locals from the outer function
558// in the inner function makes these part of the debugger information on the
559// closure. Use the inner function as well...
560BeginTest("Closure 4");
561
562function closure_4(a, b) {
563 var x = a + 2;
564 var y = b + 2;
565 function f() {
566 debugger;
567 if (f) {
568 return a + b + x + y;
569 }
570 };
571 return f;
572}
573
574listener_delegate = function(exec_state) {
575 CheckScopeChain([debug.ScopeType.Local,
576 debug.ScopeType.Closure,
577 debug.ScopeType.Global], exec_state);
578 CheckScopeContent({a:1,b:2,x:3,y:4,f:function(){}}, 1, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000579};
580closure_4(1, 2)();
Steve Blocka7e24c12009-10-30 11:49:00 +0000581EndTest();
582
583
584
585// Simple closure formed by returning an inner function referering the outer
586// functions arguments. In the presence of eval all arguments and locals
587// (including the inner function itself) from the outer function becomes part of
588// the debugger infformation on the closure.
589BeginTest("Closure 5");
590
591function closure_5(a, b) {
592 var x = 3;
593 var y = 4;
594 function f() {
595 eval('');
596 debugger;
597 return 1;
598 };
599 return f;
600}
601
602listener_delegate = function(exec_state) {
603 CheckScopeChain([debug.ScopeType.Local,
604 debug.ScopeType.Closure,
605 debug.ScopeType.Global], exec_state);
606 CheckScopeContent({a:1,b:2,x:3,y:4,f:function(){}}, 1, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000607};
608closure_5(1, 2)();
Steve Blocka7e24c12009-10-30 11:49:00 +0000609EndTest();
610
611
612// Two closures. Due to optimizations only the parts actually used are provided
613// through the debugger information.
614BeginTest("Closure 6");
615function closure_6(a, b) {
616 function f(a, b) {
617 var x = 3;
618 var y = 4;
619 return function() {
620 var x = 3;
621 var y = 4;
622 debugger;
623 some_global = a;
624 return f;
Ben Murdoch257744e2011-11-30 15:57:28 +0000625 };
Steve Blocka7e24c12009-10-30 11:49:00 +0000626 }
627 return f(a, b);
628}
629
630listener_delegate = function(exec_state) {
631 CheckScopeChain([debug.ScopeType.Local,
632 debug.ScopeType.Closure,
633 debug.ScopeType.Closure,
634 debug.ScopeType.Global], exec_state);
635 CheckScopeContent({a:1}, 1, exec_state);
636 CheckScopeContent({f:function(){}}, 2, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000637};
638closure_6(1, 2)();
Steve Blocka7e24c12009-10-30 11:49:00 +0000639EndTest();
640
641
642// Two closures. In the presence of eval all information is provided as the
643// compiler cannot determine which parts are used.
644BeginTest("Closure 7");
645function closure_7(a, b) {
646 var x = 3;
647 var y = 4;
648 eval('var i = 5');
649 eval('var j = 6');
650 function f(a, b) {
651 var x = 3;
652 var y = 4;
653 eval('var i = 5');
654 eval('var j = 6');
655 return function() {
656 debugger;
657 some_global = a;
658 return f;
Ben Murdoch257744e2011-11-30 15:57:28 +0000659 };
Steve Blocka7e24c12009-10-30 11:49:00 +0000660 }
661 return f(a, b);
662}
663
664listener_delegate = function(exec_state) {
665 CheckScopeChain([debug.ScopeType.Local,
666 debug.ScopeType.Closure,
667 debug.ScopeType.Closure,
668 debug.ScopeType.Global], exec_state);
669 CheckScopeContent({}, 0, exec_state);
670 CheckScopeContent({a:1,b:2,x:3,y:4,i:5,j:6}, 1, exec_state);
671 CheckScopeContent({a:1,b:2,x:3,y:4,i:5,j:6,f:function(){}}, 2, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000672};
673closure_7(1, 2)();
Ben Murdoch8b112d22011-06-08 16:22:53 +0100674EndTest();
675
676
677// Closure that may be optimized out.
678BeginTest("Closure 8");
679function closure_8() {
680 (function inner(x) {
681 debugger;
682 })(2);
Steve Blocka7e24c12009-10-30 11:49:00 +0000683}
Ben Murdoch8b112d22011-06-08 16:22:53 +0100684
685listener_delegate = function(exec_state) {
686 CheckScopeChain([debug.ScopeType.Local,
687 debug.ScopeType.Global], exec_state);
688 CheckScopeContent({x: 2}, 0, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000689};
Ben Murdoch8b112d22011-06-08 16:22:53 +0100690closure_8();
691EndTest();
692
693
694BeginTest("Closure 9");
695function closure_9() {
696 eval("var y = 1;");
697 eval("var z = 1;");
698 (function inner(x) {
Ben Murdoch257744e2011-11-30 15:57:28 +0000699 y++;
Ben Murdoch8b112d22011-06-08 16:22:53 +0100700 z++;
701 debugger;
702 })(2);
703}
704
705listener_delegate = function(exec_state) {
706 CheckScopeChain([debug.ScopeType.Local,
707 debug.ScopeType.Closure,
708 debug.ScopeType.Global], exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000709};
Ben Murdoch8b112d22011-06-08 16:22:53 +0100710closure_9();
Steve Blocka7e24c12009-10-30 11:49:00 +0000711EndTest();
712
713
714// Test a mixture of scopes.
715BeginTest("The full monty");
716function the_full_monty(a, b) {
717 var x = 3;
718 var y = 4;
719 eval('var i = 5');
720 eval('var j = 6');
721 function f(a, b) {
722 var x = 9;
723 var y = 10;
724 eval('var i = 11');
725 eval('var j = 12');
726 with ({j:13}){
727 return function() {
728 var x = 14;
Steve Block6ded16b2010-05-10 14:33:55 +0100729 with ({a:15}) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000730 with ({b:16}) {
731 debugger;
732 some_global = a;
733 return f;
734 }
735 }
Ben Murdoch257744e2011-11-30 15:57:28 +0000736 };
Steve Blocka7e24c12009-10-30 11:49:00 +0000737 }
738 }
739 return f(a, b);
740}
741
742listener_delegate = function(exec_state) {
743 CheckScopeChain([debug.ScopeType.With,
744 debug.ScopeType.With,
745 debug.ScopeType.Local,
746 debug.ScopeType.With,
747 debug.ScopeType.Closure,
748 debug.ScopeType.Closure,
749 debug.ScopeType.Global], exec_state);
750 CheckScopeContent({b:16}, 0, exec_state);
751 CheckScopeContent({a:15}, 1, exec_state);
752 CheckScopeContent({x:14}, 2, exec_state);
753 CheckScopeContent({j:13}, 3, exec_state);
754 CheckScopeContent({a:1,b:2,x:9,y:10,i:11,j:12}, 4, exec_state);
755 CheckScopeContent({a:1,b:2,x:3,y:4,i:5,j:6,f:function(){}}, 5, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000756};
757the_full_monty(1, 2)();
Steve Blocka7e24c12009-10-30 11:49:00 +0000758EndTest();
759
Ben Murdoch8b112d22011-06-08 16:22:53 +0100760
761BeginTest("Closure inside With 1");
762function closure_in_with_1() {
763 with({x:1}) {
764 (function inner(x) {
765 debugger;
766 })(2);
767 }
768}
769
770listener_delegate = function(exec_state) {
771 CheckScopeChain([debug.ScopeType.Local,
772 debug.ScopeType.With,
773 debug.ScopeType.Closure,
774 debug.ScopeType.Global], exec_state);
775 CheckScopeContent({x: 2}, 0, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000776};
Ben Murdoch8b112d22011-06-08 16:22:53 +0100777closure_in_with_1();
778EndTest();
779
780
781BeginTest("Closure inside With 2");
782function closure_in_with_2() {
783 with({x:1}) {
784 (function inner(x) {
785 with({x:3}) {
786 debugger;
787 }
788 })(2);
789 }
790}
791
792listener_delegate = function(exec_state) {
793 CheckScopeChain([debug.ScopeType.With,
794 debug.ScopeType.Local,
795 debug.ScopeType.With,
796 debug.ScopeType.Closure,
797 debug.ScopeType.Global], exec_state);
798 CheckScopeContent({x: 3}, 0, exec_state);
799 CheckScopeContent({x: 2}, 1, exec_state);
800 CheckScopeContent({x: 1}, 2, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000801};
Ben Murdoch8b112d22011-06-08 16:22:53 +0100802closure_in_with_2();
803EndTest();
804
805
806BeginTest("Closure inside With 3");
807function createClosure(a) {
808 var b = a + 1;
809 return function closure() {
810 var c = b;
811 (function inner(x) {
812 with({x:c}) {
813 debugger;
814 }
815 })(2);
Ben Murdoch257744e2011-11-30 15:57:28 +0000816 };
Ben Murdoch8b112d22011-06-08 16:22:53 +0100817}
818
819function closure_in_with_3() {
820 var f = createClosure(0);
821 f();
822}
823
824listener_delegate = function(exec_state) {
825 CheckScopeChain([debug.ScopeType.With,
826 debug.ScopeType.Local,
827 debug.ScopeType.Closure,
828 debug.ScopeType.Closure,
829 debug.ScopeType.Global], exec_state);
830}
831closure_in_with_3();
832EndTest();
833
834
Ben Murdoch589d6972011-11-30 16:04:58 +0000835BeginTest("Closure inside With 4");
836listener_delegate = function(exec_state) {
837 CheckScopeChain([debug.ScopeType.Local,
838 debug.ScopeType.With,
839 debug.ScopeType.Global], exec_state);
840 CheckScopeContent({x: 2}, 0, exec_state);
841 CheckScopeContent({x: 1}, 1, exec_state);
842};
843
844with({x:1}) {
845 (function(x) {
846 debugger;
847 })(2);
848}
849EndTest();
850
851
Steve Blocka7e24c12009-10-30 11:49:00 +0000852// Test global scope.
853BeginTest("Global");
854listener_delegate = function(exec_state) {
855 CheckScopeChain([debug.ScopeType.Global], exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000856};
Steve Blocka7e24c12009-10-30 11:49:00 +0000857debugger;
858EndTest();
859
860
861BeginTest("Catch block 1");
862function catch_block_1() {
863 try {
864 throw 'Exception';
865 } catch (e) {
866 debugger;
867 }
868};
869
870
871listener_delegate = function(exec_state) {
872 CheckScopeChain([debug.ScopeType.Catch,
873 debug.ScopeType.Local,
874 debug.ScopeType.Global], exec_state);
875 CheckScopeContent({e:'Exception'}, 0, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000876};
877catch_block_1();
Steve Blocka7e24c12009-10-30 11:49:00 +0000878EndTest();
879
880
881BeginTest("Catch block 2");
882function catch_block_2() {
883 try {
884 throw 'Exception';
885 } catch (e) {
886 with({n:10}) {
887 debugger;
888 }
889 }
890};
891
892
893listener_delegate = function(exec_state) {
894 CheckScopeChain([debug.ScopeType.With,
895 debug.ScopeType.Catch,
896 debug.ScopeType.Local,
897 debug.ScopeType.Global], exec_state);
898 CheckScopeContent({n:10}, 0, exec_state);
899 CheckScopeContent({e:'Exception'}, 1, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000900};
901catch_block_2();
Steve Blocka7e24c12009-10-30 11:49:00 +0000902EndTest();
903
904
905BeginTest("Catch block 3");
Steve Block6ded16b2010-05-10 14:33:55 +0100906function catch_block_3() {
Steve Blocka7e24c12009-10-30 11:49:00 +0000907 // Do eval to dynamically declare a local variable so that the context's
908 // extension slot is initialized with JSContextExtensionObject.
909 eval("var y = 78;");
910 try {
911 throw 'Exception';
912 } catch (e) {
913 debugger;
914 }
915};
916
917
918listener_delegate = function(exec_state) {
919 CheckScopeChain([debug.ScopeType.Catch,
920 debug.ScopeType.Local,
921 debug.ScopeType.Global], exec_state);
922 CheckScopeContent({e:'Exception'}, 0, exec_state);
923 CheckScopeContent({y:78}, 1, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000924};
925catch_block_3();
Steve Blocka7e24c12009-10-30 11:49:00 +0000926EndTest();
927
928
929BeginTest("Catch block 4");
Steve Block6ded16b2010-05-10 14:33:55 +0100930function catch_block_4() {
Steve Blocka7e24c12009-10-30 11:49:00 +0000931 // Do eval to dynamically declare a local variable so that the context's
932 // extension slot is initialized with JSContextExtensionObject.
933 eval("var y = 98;");
934 try {
935 throw 'Exception';
936 } catch (e) {
937 with({n:10}) {
938 debugger;
939 }
940 }
941};
942
943listener_delegate = function(exec_state) {
944 CheckScopeChain([debug.ScopeType.With,
945 debug.ScopeType.Catch,
946 debug.ScopeType.Local,
947 debug.ScopeType.Global], exec_state);
948 CheckScopeContent({n:10}, 0, exec_state);
949 CheckScopeContent({e:'Exception'}, 1, exec_state);
950 CheckScopeContent({y:98}, 2, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000951};
952catch_block_4();
Steve Blocka7e24c12009-10-30 11:49:00 +0000953EndTest();
954
955
Ben Murdoch589d6972011-11-30 16:04:58 +0000956// Test catch in global scope.
957BeginTest("Catch block 5");
958listener_delegate = function(exec_state) {
959 CheckScopeChain([debug.ScopeType.Catch,
960 debug.ScopeType.Global], exec_state);
961 CheckScopeContent({e:'Exception'}, 0, exec_state);
962};
963
964try {
965 throw 'Exception';
966} catch (e) {
967 debugger;
968}
969
970EndTest();
971
972
973// Closure inside catch in global code.
974BeginTest("Catch block 6");
975listener_delegate = function(exec_state) {
976 CheckScopeChain([debug.ScopeType.Local,
977 debug.ScopeType.Catch,
978 debug.ScopeType.Global], exec_state);
979 CheckScopeContent({x: 2}, 0, exec_state);
980 CheckScopeContent({e:'Exception'}, 1, exec_state);
981};
982
983try {
984 throw 'Exception';
985} catch (e) {
986 (function(x) {
987 debugger;
988 })(2);
989}
990EndTest();
991
992
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100993// Catch block in function that is marked for optimization while being executed.
994BeginTest("Catch block 7");
995function catch_block_7() {
996 %OptimizeFunctionOnNextCall(catch_block_7);
997 try {
998 throw 'Exception';
999 } catch (e) {
1000 debugger;
1001 }
1002};
1003
1004
1005listener_delegate = function(exec_state) {
1006 CheckScopeChain([debug.ScopeType.Catch,
1007 debug.ScopeType.Local,
1008 debug.ScopeType.Global], exec_state);
1009 CheckScopeContent({e:'Exception'}, 0, exec_state);
1010};
1011catch_block_7();
1012EndTest();
1013
1014
Ben Murdoch257744e2011-11-30 15:57:28 +00001015assertEquals(begin_test_count, break_count,
1016 'one or more tests did not enter the debugger');
1017assertEquals(begin_test_count, end_test_count,
1018 'one or more tests did not have its result checked');