blob: 7c08120e2adf82e753117726d253263a9d170966 [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 ||
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400133 scopes[i] == debug.ScopeType.Script ||
Steve Blocka7e24c12009-10-30 11:49:00 +0000134 scopes[i] == debug.ScopeType.Closure) {
135 assertTrue(response.body.scopes[i].object.ref < 0);
136 } else {
137 assertTrue(response.body.scopes[i].object.ref >= 0);
138 }
139 var found = false;
140 for (var j = 0; j < response.refs.length && !found; j++) {
141 found = response.refs[j].handle == response.body.scopes[i].object.ref;
142 }
143 assertTrue(found, "Scope object " + response.body.scopes[i].object.ref + " not found");
144 }
145}
146
147
148// Check that the content of the scope is as expected. For functions just check
149// that there is a function.
150function CheckScopeContent(content, number, exec_state) {
Ben Murdoch257744e2011-11-30 15:57:28 +0000151 var scope = exec_state.frame().scope(number);
Steve Blocka7e24c12009-10-30 11:49:00 +0000152 var count = 0;
153 for (var p in content) {
154 var property_mirror = scope.scopeObject().property(p);
155 assertFalse(property_mirror.isUndefined(), 'property ' + p + ' not found in scope');
156 if (typeof(content[p]) === 'function') {
157 assertTrue(property_mirror.value().isFunction());
158 } else {
159 assertEquals(content[p], property_mirror.value().value(), 'property ' + p + ' has unexpected value');
160 }
161 count++;
162 }
Steve Block6ded16b2010-05-10 14:33:55 +0100163
Steve Blocka7e24c12009-10-30 11:49:00 +0000164 // 'arguments' and might be exposed in the local and closure scope. Just
165 // ignore this.
166 var scope_size = scope.scopeObject().properties().length;
167 if (!scope.scopeObject().property('arguments').isUndefined()) {
168 scope_size--;
169 }
Ben Murdoch8b112d22011-06-08 16:22:53 +0100170 // Skip property with empty name.
171 if (!scope.scopeObject().property('').isUndefined()) {
172 scope_size--;
173 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000174
175 if (count != scope_size) {
176 print('Names found in scope:');
177 var names = scope.scopeObject().propertyNames();
178 for (var i = 0; i < names.length; i++) {
179 print(names[i]);
180 }
181 }
182 assertEquals(count, scope_size);
183
184 // Get the debug command processor.
Steve Block3ce2e202009-11-05 08:53:23 +0000185 var dcp = exec_state.debugCommandProcessor("unspecified_running_state");
Steve Block6ded16b2010-05-10 14:33:55 +0100186
Steve Blocka7e24c12009-10-30 11:49:00 +0000187 // Send a scope request for information on a single scope and check the
188 // result.
Ben Murdoch257744e2011-11-30 15:57:28 +0000189 var request_json = '{"seq":0,"type":"request","command":"scope","arguments":{"number":';
Steve Blocka7e24c12009-10-30 11:49:00 +0000190 request_json += scope.scopeIndex();
Ben Murdoch257744e2011-11-30 15:57:28 +0000191 request_json += '}}';
Steve Blocka7e24c12009-10-30 11:49:00 +0000192 var response_json = dcp.processDebugJSONRequest(request_json);
193 var response = JSON.parse(response_json);
194 assertEquals(scope.scopeType(), response.body.type);
195 assertEquals(number, response.body.index);
196 if (scope.scopeType() == debug.ScopeType.Local ||
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400197 scope.scopeType() == debug.ScopeType.Script ||
Steve Blocka7e24c12009-10-30 11:49:00 +0000198 scope.scopeType() == debug.ScopeType.Closure) {
199 assertTrue(response.body.object.ref < 0);
200 } else {
201 assertTrue(response.body.object.ref >= 0);
202 }
203 var found = false;
204 for (var i = 0; i < response.refs.length && !found; i++) {
205 found = response.refs[i].handle == response.body.object.ref;
206 }
207 assertTrue(found, "Scope object " + response.body.object.ref + " not found");
208}
209
210
211// Simple empty local scope.
212BeginTest("Local 1");
213
214function local_1() {
215 debugger;
216}
217
218listener_delegate = function(exec_state) {
219 CheckScopeChain([debug.ScopeType.Local,
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400220 debug.ScopeType.Script,
Steve Blocka7e24c12009-10-30 11:49:00 +0000221 debug.ScopeType.Global], exec_state);
222 CheckScopeContent({}, 0, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000223};
224local_1();
Steve Blocka7e24c12009-10-30 11:49:00 +0000225EndTest();
226
227
228// Local scope with a parameter.
229BeginTest("Local 2");
230
231function local_2(a) {
232 debugger;
233}
234
235listener_delegate = function(exec_state) {
236 CheckScopeChain([debug.ScopeType.Local,
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400237 debug.ScopeType.Script,
Steve Blocka7e24c12009-10-30 11:49:00 +0000238 debug.ScopeType.Global], exec_state);
239 CheckScopeContent({a:1}, 0, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000240};
241local_2(1);
Steve Blocka7e24c12009-10-30 11:49:00 +0000242EndTest();
243
244
245// Local scope with a parameter and a local variable.
246BeginTest("Local 3");
247
248function local_3(a) {
249 var x = 3;
250 debugger;
251}
252
253listener_delegate = function(exec_state) {
254 CheckScopeChain([debug.ScopeType.Local,
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400255 debug.ScopeType.Script,
Steve Blocka7e24c12009-10-30 11:49:00 +0000256 debug.ScopeType.Global], exec_state);
257 CheckScopeContent({a:1,x:3}, 0, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000258};
259local_3(1);
Steve Blocka7e24c12009-10-30 11:49:00 +0000260EndTest();
261
262
263// Local scope with parameters and local variables.
264BeginTest("Local 4");
265
266function local_4(a, b) {
267 var x = 3;
268 var y = 4;
269 debugger;
270}
271
272listener_delegate = function(exec_state) {
273 CheckScopeChain([debug.ScopeType.Local,
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400274 debug.ScopeType.Script,
Steve Blocka7e24c12009-10-30 11:49:00 +0000275 debug.ScopeType.Global], exec_state);
276 CheckScopeContent({a:1,b:2,x:3,y:4}, 0, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000277};
278local_4(1, 2);
Steve Blocka7e24c12009-10-30 11:49:00 +0000279EndTest();
280
281
282// Empty local scope with use of eval.
283BeginTest("Local 5");
284
285function local_5() {
286 eval('');
287 debugger;
288}
289
290listener_delegate = function(exec_state) {
291 CheckScopeChain([debug.ScopeType.Local,
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400292 debug.ScopeType.Script,
Steve Blocka7e24c12009-10-30 11:49:00 +0000293 debug.ScopeType.Global], exec_state);
294 CheckScopeContent({}, 0, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000295};
296local_5();
Steve Blocka7e24c12009-10-30 11:49:00 +0000297EndTest();
298
299
300// Local introducing local variable using eval.
301BeginTest("Local 6");
302
303function local_6() {
304 eval('var i = 5');
305 debugger;
306}
307
308listener_delegate = function(exec_state) {
309 CheckScopeChain([debug.ScopeType.Local,
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400310 debug.ScopeType.Script,
Steve Blocka7e24c12009-10-30 11:49:00 +0000311 debug.ScopeType.Global], exec_state);
312 CheckScopeContent({i:5}, 0, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000313};
314local_6();
Steve Blocka7e24c12009-10-30 11:49:00 +0000315EndTest();
316
317
318// Local scope with parameters, local variables and local variable introduced
319// using eval.
320BeginTest("Local 7");
321
322function local_7(a, b) {
323 var x = 3;
324 var y = 4;
325 eval('var i = 5');
326 eval('var j = 6');
327 debugger;
328}
329
330listener_delegate = function(exec_state) {
331 CheckScopeChain([debug.ScopeType.Local,
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400332 debug.ScopeType.Script,
Steve Blocka7e24c12009-10-30 11:49:00 +0000333 debug.ScopeType.Global], exec_state);
334 CheckScopeContent({a:1,b:2,x:3,y:4,i:5,j:6}, 0, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000335};
336local_7(1, 2);
Steve Blocka7e24c12009-10-30 11:49:00 +0000337EndTest();
338
339
340// Single empty with block.
341BeginTest("With 1");
342
343function with_1() {
344 with({}) {
345 debugger;
346 }
347}
348
349listener_delegate = function(exec_state) {
350 CheckScopeChain([debug.ScopeType.With,
351 debug.ScopeType.Local,
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400352 debug.ScopeType.Script,
Steve Blocka7e24c12009-10-30 11:49:00 +0000353 debug.ScopeType.Global], exec_state);
354 CheckScopeContent({}, 0, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000355};
356with_1();
Steve Blocka7e24c12009-10-30 11:49:00 +0000357EndTest();
358
359
360// Nested empty with blocks.
361BeginTest("With 2");
362
363function with_2() {
364 with({}) {
365 with({}) {
366 debugger;
367 }
368 }
369}
370
371listener_delegate = function(exec_state) {
372 CheckScopeChain([debug.ScopeType.With,
373 debug.ScopeType.With,
374 debug.ScopeType.Local,
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400375 debug.ScopeType.Script,
Steve Blocka7e24c12009-10-30 11:49:00 +0000376 debug.ScopeType.Global], exec_state);
377 CheckScopeContent({}, 0, exec_state);
378 CheckScopeContent({}, 1, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000379};
380with_2();
Steve Blocka7e24c12009-10-30 11:49:00 +0000381EndTest();
382
383
384// With block using an in-place object literal.
385BeginTest("With 3");
386
387function with_3() {
388 with({a:1,b:2}) {
389 debugger;
390 }
391}
392
393listener_delegate = function(exec_state) {
394 CheckScopeChain([debug.ScopeType.With,
395 debug.ScopeType.Local,
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400396 debug.ScopeType.Script,
Steve Blocka7e24c12009-10-30 11:49:00 +0000397 debug.ScopeType.Global], exec_state);
398 CheckScopeContent({a:1,b:2}, 0, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000399};
400with_3();
Steve Blocka7e24c12009-10-30 11:49:00 +0000401EndTest();
402
403
404// Nested with blocks using in-place object literals.
405BeginTest("With 4");
406
407function with_4() {
408 with({a:1,b:2}) {
409 with({a:2,b:1}) {
410 debugger;
411 }
412 }
413}
414
415listener_delegate = function(exec_state) {
416 CheckScopeChain([debug.ScopeType.With,
417 debug.ScopeType.With,
418 debug.ScopeType.Local,
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400419 debug.ScopeType.Script,
Steve Blocka7e24c12009-10-30 11:49:00 +0000420 debug.ScopeType.Global], exec_state);
421 CheckScopeContent({a:2,b:1}, 0, exec_state);
422 CheckScopeContent({a:1,b:2}, 1, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000423};
424with_4();
Steve Blocka7e24c12009-10-30 11:49:00 +0000425EndTest();
426
427
428// Nested with blocks using existing object.
429BeginTest("With 5");
430
431var with_object = {c:3,d:4};
432function with_5() {
433 with(with_object) {
434 with(with_object) {
435 debugger;
436 }
437 }
438}
439
440listener_delegate = function(exec_state) {
441 CheckScopeChain([debug.ScopeType.With,
442 debug.ScopeType.With,
443 debug.ScopeType.Local,
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400444 debug.ScopeType.Script,
Steve Blocka7e24c12009-10-30 11:49:00 +0000445 debug.ScopeType.Global], exec_state);
446 CheckScopeContent(with_object, 0, exec_state);
447 CheckScopeContent(with_object, 1, exec_state);
448 assertEquals(exec_state.frame().scope(0).scopeObject(), exec_state.frame().scope(1).scopeObject());
449 assertEquals(with_object, exec_state.frame().scope(1).scopeObject().value());
Ben Murdoch257744e2011-11-30 15:57:28 +0000450};
451with_5();
Steve Blocka7e24c12009-10-30 11:49:00 +0000452EndTest();
453
454
Ben Murdoch589d6972011-11-30 16:04:58 +0000455// Nested with blocks using existing object in global code.
456BeginTest("With 6");
457listener_delegate = function(exec_state) {
458 CheckScopeChain([debug.ScopeType.With,
459 debug.ScopeType.With,
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400460 debug.ScopeType.Script,
Ben Murdoch589d6972011-11-30 16:04:58 +0000461 debug.ScopeType.Global], exec_state);
462 CheckScopeContent(with_object, 0, exec_state);
463 CheckScopeContent(with_object, 1, exec_state);
464 assertEquals(exec_state.frame().scope(0).scopeObject(), exec_state.frame().scope(1).scopeObject());
465 assertEquals(with_object, exec_state.frame().scope(1).scopeObject().value());
466};
467
468var with_object = {c:3,d:4};
469with(with_object) {
470 with(with_object) {
471 debugger;
472 }
473}
474EndTest();
475
476
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100477// With block in function that is marked for optimization while being executed.
478BeginTest("With 7");
479
480function with_7() {
481 with({}) {
482 %OptimizeFunctionOnNextCall(with_7);
483 debugger;
484 }
485}
486
487listener_delegate = function(exec_state) {
488 CheckScopeChain([debug.ScopeType.With,
489 debug.ScopeType.Local,
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400490 debug.ScopeType.Script,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100491 debug.ScopeType.Global], exec_state);
492 CheckScopeContent({}, 0, exec_state);
493};
494with_7();
495EndTest();
496
497
Steve Blocka7e24c12009-10-30 11:49:00 +0000498// Simple closure formed by returning an inner function referering the outer
499// functions arguments.
500BeginTest("Closure 1");
501
502function closure_1(a) {
503 function f() {
504 debugger;
505 return a;
506 };
507 return f;
508}
509
510listener_delegate = function(exec_state) {
511 CheckScopeChain([debug.ScopeType.Local,
512 debug.ScopeType.Closure,
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400513 debug.ScopeType.Script,
Steve Blocka7e24c12009-10-30 11:49:00 +0000514 debug.ScopeType.Global], exec_state);
515 CheckScopeContent({a:1}, 1, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000516};
517closure_1(1)();
Steve Blocka7e24c12009-10-30 11:49:00 +0000518EndTest();
519
520
521// Simple closure formed by returning an inner function referering the outer
522// functions arguments. Due to VM optimizations parts of the actual closure is
523// missing from the debugger information.
524BeginTest("Closure 2");
525
526function closure_2(a, b) {
527 var x = a + 2;
528 var y = b + 2;
529 function f() {
530 debugger;
531 return a + x;
532 };
533 return f;
534}
535
536listener_delegate = function(exec_state) {
537 CheckScopeChain([debug.ScopeType.Local,
538 debug.ScopeType.Closure,
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400539 debug.ScopeType.Script,
Steve Blocka7e24c12009-10-30 11:49:00 +0000540 debug.ScopeType.Global], exec_state);
541 CheckScopeContent({a:1,x:3}, 1, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000542};
543closure_2(1, 2)();
Steve Blocka7e24c12009-10-30 11:49:00 +0000544EndTest();
545
546
547// Simple closure formed by returning an inner function referering the outer
548// functions arguments. Using all arguments and locals from the outer function
549// in the inner function makes these part of the debugger information on the
550// closure.
551BeginTest("Closure 3");
552
553function closure_3(a, b) {
554 var x = a + 2;
555 var y = b + 2;
556 function f() {
557 debugger;
558 return a + b + x + y;
559 };
560 return f;
561}
562
563listener_delegate = function(exec_state) {
564 CheckScopeChain([debug.ScopeType.Local,
565 debug.ScopeType.Closure,
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400566 debug.ScopeType.Script,
Steve Blocka7e24c12009-10-30 11:49:00 +0000567 debug.ScopeType.Global], exec_state);
568 CheckScopeContent({a:1,b:2,x:3,y:4}, 1, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000569};
570closure_3(1, 2)();
Steve Blocka7e24c12009-10-30 11:49:00 +0000571EndTest();
572
573
574
575// Simple closure formed by returning an inner function referering the outer
576// functions arguments. Using all arguments and locals from the outer function
577// in the inner function makes these part of the debugger information on the
578// closure. Use the inner function as well...
579BeginTest("Closure 4");
580
581function closure_4(a, b) {
582 var x = a + 2;
583 var y = b + 2;
584 function f() {
585 debugger;
586 if (f) {
587 return a + b + x + y;
588 }
589 };
590 return f;
591}
592
593listener_delegate = function(exec_state) {
594 CheckScopeChain([debug.ScopeType.Local,
595 debug.ScopeType.Closure,
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400596 debug.ScopeType.Script,
Steve Blocka7e24c12009-10-30 11:49:00 +0000597 debug.ScopeType.Global], exec_state);
598 CheckScopeContent({a:1,b:2,x:3,y:4,f:function(){}}, 1, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000599};
600closure_4(1, 2)();
Steve Blocka7e24c12009-10-30 11:49:00 +0000601EndTest();
602
603
604
605// Simple closure formed by returning an inner function referering the outer
606// functions arguments. In the presence of eval all arguments and locals
607// (including the inner function itself) from the outer function becomes part of
608// the debugger infformation on the closure.
609BeginTest("Closure 5");
610
611function closure_5(a, b) {
612 var x = 3;
613 var y = 4;
614 function f() {
615 eval('');
616 debugger;
617 return 1;
618 };
619 return f;
620}
621
622listener_delegate = function(exec_state) {
623 CheckScopeChain([debug.ScopeType.Local,
624 debug.ScopeType.Closure,
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400625 debug.ScopeType.Script,
Steve Blocka7e24c12009-10-30 11:49:00 +0000626 debug.ScopeType.Global], exec_state);
627 CheckScopeContent({a:1,b:2,x:3,y:4,f:function(){}}, 1, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000628};
629closure_5(1, 2)();
Steve Blocka7e24c12009-10-30 11:49:00 +0000630EndTest();
631
632
633// Two closures. Due to optimizations only the parts actually used are provided
634// through the debugger information.
635BeginTest("Closure 6");
636function closure_6(a, b) {
637 function f(a, b) {
638 var x = 3;
639 var y = 4;
640 return function() {
641 var x = 3;
642 var y = 4;
643 debugger;
644 some_global = a;
645 return f;
Ben Murdoch257744e2011-11-30 15:57:28 +0000646 };
Steve Blocka7e24c12009-10-30 11:49:00 +0000647 }
648 return f(a, b);
649}
650
651listener_delegate = function(exec_state) {
652 CheckScopeChain([debug.ScopeType.Local,
653 debug.ScopeType.Closure,
654 debug.ScopeType.Closure,
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400655 debug.ScopeType.Script,
Steve Blocka7e24c12009-10-30 11:49:00 +0000656 debug.ScopeType.Global], exec_state);
657 CheckScopeContent({a:1}, 1, exec_state);
658 CheckScopeContent({f:function(){}}, 2, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000659};
660closure_6(1, 2)();
Steve Blocka7e24c12009-10-30 11:49:00 +0000661EndTest();
662
663
664// Two closures. In the presence of eval all information is provided as the
665// compiler cannot determine which parts are used.
666BeginTest("Closure 7");
667function closure_7(a, b) {
668 var x = 3;
669 var y = 4;
670 eval('var i = 5');
671 eval('var j = 6');
672 function f(a, b) {
673 var x = 3;
674 var y = 4;
675 eval('var i = 5');
676 eval('var j = 6');
677 return function() {
678 debugger;
679 some_global = a;
680 return f;
Ben Murdoch257744e2011-11-30 15:57:28 +0000681 };
Steve Blocka7e24c12009-10-30 11:49:00 +0000682 }
683 return f(a, b);
684}
685
686listener_delegate = function(exec_state) {
687 CheckScopeChain([debug.ScopeType.Local,
688 debug.ScopeType.Closure,
689 debug.ScopeType.Closure,
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400690 debug.ScopeType.Script,
Steve Blocka7e24c12009-10-30 11:49:00 +0000691 debug.ScopeType.Global], exec_state);
692 CheckScopeContent({}, 0, exec_state);
693 CheckScopeContent({a:1,b:2,x:3,y:4,i:5,j:6}, 1, exec_state);
694 CheckScopeContent({a:1,b:2,x:3,y:4,i:5,j:6,f:function(){}}, 2, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000695};
696closure_7(1, 2)();
Ben Murdoch8b112d22011-06-08 16:22:53 +0100697EndTest();
698
699
700// Closure that may be optimized out.
701BeginTest("Closure 8");
702function closure_8() {
703 (function inner(x) {
704 debugger;
705 })(2);
Steve Blocka7e24c12009-10-30 11:49:00 +0000706}
Ben Murdoch8b112d22011-06-08 16:22:53 +0100707
708listener_delegate = function(exec_state) {
709 CheckScopeChain([debug.ScopeType.Local,
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400710 debug.ScopeType.Script,
Ben Murdoch8b112d22011-06-08 16:22:53 +0100711 debug.ScopeType.Global], exec_state);
712 CheckScopeContent({x: 2}, 0, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000713};
Ben Murdoch8b112d22011-06-08 16:22:53 +0100714closure_8();
715EndTest();
716
717
718BeginTest("Closure 9");
719function closure_9() {
720 eval("var y = 1;");
721 eval("var z = 1;");
722 (function inner(x) {
Ben Murdoch257744e2011-11-30 15:57:28 +0000723 y++;
Ben Murdoch8b112d22011-06-08 16:22:53 +0100724 z++;
725 debugger;
726 })(2);
727}
728
729listener_delegate = function(exec_state) {
730 CheckScopeChain([debug.ScopeType.Local,
731 debug.ScopeType.Closure,
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400732 debug.ScopeType.Script,
Ben Murdoch8b112d22011-06-08 16:22:53 +0100733 debug.ScopeType.Global], exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000734};
Ben Murdoch8b112d22011-06-08 16:22:53 +0100735closure_9();
Steve Blocka7e24c12009-10-30 11:49:00 +0000736EndTest();
737
738
739// Test a mixture of scopes.
740BeginTest("The full monty");
741function the_full_monty(a, b) {
742 var x = 3;
743 var y = 4;
744 eval('var i = 5');
745 eval('var j = 6');
746 function f(a, b) {
747 var x = 9;
748 var y = 10;
749 eval('var i = 11');
750 eval('var j = 12');
751 with ({j:13}){
752 return function() {
753 var x = 14;
Steve Block6ded16b2010-05-10 14:33:55 +0100754 with ({a:15}) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000755 with ({b:16}) {
756 debugger;
757 some_global = a;
758 return f;
759 }
760 }
Ben Murdoch257744e2011-11-30 15:57:28 +0000761 };
Steve Blocka7e24c12009-10-30 11:49:00 +0000762 }
763 }
764 return f(a, b);
765}
766
767listener_delegate = function(exec_state) {
768 CheckScopeChain([debug.ScopeType.With,
769 debug.ScopeType.With,
770 debug.ScopeType.Local,
771 debug.ScopeType.With,
772 debug.ScopeType.Closure,
773 debug.ScopeType.Closure,
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400774 debug.ScopeType.Script,
Steve Blocka7e24c12009-10-30 11:49:00 +0000775 debug.ScopeType.Global], exec_state);
776 CheckScopeContent({b:16}, 0, exec_state);
777 CheckScopeContent({a:15}, 1, exec_state);
778 CheckScopeContent({x:14}, 2, exec_state);
779 CheckScopeContent({j:13}, 3, exec_state);
780 CheckScopeContent({a:1,b:2,x:9,y:10,i:11,j:12}, 4, exec_state);
781 CheckScopeContent({a:1,b:2,x:3,y:4,i:5,j:6,f:function(){}}, 5, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000782};
783the_full_monty(1, 2)();
Steve Blocka7e24c12009-10-30 11:49:00 +0000784EndTest();
785
Ben Murdoch8b112d22011-06-08 16:22:53 +0100786
787BeginTest("Closure inside With 1");
788function closure_in_with_1() {
789 with({x:1}) {
790 (function inner(x) {
791 debugger;
792 })(2);
793 }
794}
795
796listener_delegate = function(exec_state) {
797 CheckScopeChain([debug.ScopeType.Local,
798 debug.ScopeType.With,
799 debug.ScopeType.Closure,
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400800 debug.ScopeType.Script,
Ben Murdoch8b112d22011-06-08 16:22:53 +0100801 debug.ScopeType.Global], exec_state);
802 CheckScopeContent({x: 2}, 0, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000803};
Ben Murdoch8b112d22011-06-08 16:22:53 +0100804closure_in_with_1();
805EndTest();
806
807
808BeginTest("Closure inside With 2");
809function closure_in_with_2() {
810 with({x:1}) {
811 (function inner(x) {
812 with({x:3}) {
813 debugger;
814 }
815 })(2);
816 }
817}
818
819listener_delegate = function(exec_state) {
820 CheckScopeChain([debug.ScopeType.With,
821 debug.ScopeType.Local,
822 debug.ScopeType.With,
823 debug.ScopeType.Closure,
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400824 debug.ScopeType.Script,
Ben Murdoch8b112d22011-06-08 16:22:53 +0100825 debug.ScopeType.Global], exec_state);
826 CheckScopeContent({x: 3}, 0, exec_state);
827 CheckScopeContent({x: 2}, 1, exec_state);
828 CheckScopeContent({x: 1}, 2, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000829};
Ben Murdoch8b112d22011-06-08 16:22:53 +0100830closure_in_with_2();
831EndTest();
832
833
834BeginTest("Closure inside With 3");
835function createClosure(a) {
836 var b = a + 1;
837 return function closure() {
838 var c = b;
839 (function inner(x) {
840 with({x:c}) {
841 debugger;
842 }
843 })(2);
Ben Murdoch257744e2011-11-30 15:57:28 +0000844 };
Ben Murdoch8b112d22011-06-08 16:22:53 +0100845}
846
847function closure_in_with_3() {
848 var f = createClosure(0);
849 f();
850}
851
852listener_delegate = function(exec_state) {
853 CheckScopeChain([debug.ScopeType.With,
854 debug.ScopeType.Local,
855 debug.ScopeType.Closure,
856 debug.ScopeType.Closure,
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400857 debug.ScopeType.Script,
Ben Murdoch8b112d22011-06-08 16:22:53 +0100858 debug.ScopeType.Global], exec_state);
859}
860closure_in_with_3();
861EndTest();
862
863
Ben Murdoch589d6972011-11-30 16:04:58 +0000864BeginTest("Closure inside With 4");
865listener_delegate = function(exec_state) {
866 CheckScopeChain([debug.ScopeType.Local,
867 debug.ScopeType.With,
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400868 debug.ScopeType.Script,
Ben Murdoch589d6972011-11-30 16:04:58 +0000869 debug.ScopeType.Global], exec_state);
870 CheckScopeContent({x: 2}, 0, exec_state);
871 CheckScopeContent({x: 1}, 1, exec_state);
872};
873
874with({x:1}) {
875 (function(x) {
876 debugger;
877 })(2);
878}
879EndTest();
880
881
Steve Blocka7e24c12009-10-30 11:49:00 +0000882// Test global scope.
883BeginTest("Global");
884listener_delegate = function(exec_state) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400885 CheckScopeChain([debug.ScopeType.Script, debug.ScopeType.Global], exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000886};
Steve Blocka7e24c12009-10-30 11:49:00 +0000887debugger;
888EndTest();
889
890
891BeginTest("Catch block 1");
892function catch_block_1() {
893 try {
894 throw 'Exception';
895 } catch (e) {
896 debugger;
897 }
898};
899
900
901listener_delegate = function(exec_state) {
902 CheckScopeChain([debug.ScopeType.Catch,
903 debug.ScopeType.Local,
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400904 debug.ScopeType.Script,
Steve Blocka7e24c12009-10-30 11:49:00 +0000905 debug.ScopeType.Global], exec_state);
906 CheckScopeContent({e:'Exception'}, 0, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000907};
908catch_block_1();
Steve Blocka7e24c12009-10-30 11:49:00 +0000909EndTest();
910
911
912BeginTest("Catch block 2");
913function catch_block_2() {
914 try {
915 throw 'Exception';
916 } catch (e) {
917 with({n:10}) {
918 debugger;
919 }
920 }
921};
922
923
924listener_delegate = function(exec_state) {
925 CheckScopeChain([debug.ScopeType.With,
926 debug.ScopeType.Catch,
927 debug.ScopeType.Local,
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400928 debug.ScopeType.Script,
Steve Blocka7e24c12009-10-30 11:49:00 +0000929 debug.ScopeType.Global], exec_state);
930 CheckScopeContent({n:10}, 0, exec_state);
931 CheckScopeContent({e:'Exception'}, 1, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000932};
933catch_block_2();
Steve Blocka7e24c12009-10-30 11:49:00 +0000934EndTest();
935
936
937BeginTest("Catch block 3");
Steve Block6ded16b2010-05-10 14:33:55 +0100938function catch_block_3() {
Steve Blocka7e24c12009-10-30 11:49:00 +0000939 // Do eval to dynamically declare a local variable so that the context's
940 // extension slot is initialized with JSContextExtensionObject.
941 eval("var y = 78;");
942 try {
943 throw 'Exception';
944 } catch (e) {
945 debugger;
946 }
947};
948
949
950listener_delegate = function(exec_state) {
951 CheckScopeChain([debug.ScopeType.Catch,
952 debug.ScopeType.Local,
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400953 debug.ScopeType.Script,
Steve Blocka7e24c12009-10-30 11:49:00 +0000954 debug.ScopeType.Global], exec_state);
955 CheckScopeContent({e:'Exception'}, 0, exec_state);
956 CheckScopeContent({y:78}, 1, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000957};
958catch_block_3();
Steve Blocka7e24c12009-10-30 11:49:00 +0000959EndTest();
960
961
962BeginTest("Catch block 4");
Steve Block6ded16b2010-05-10 14:33:55 +0100963function catch_block_4() {
Steve Blocka7e24c12009-10-30 11:49:00 +0000964 // Do eval to dynamically declare a local variable so that the context's
965 // extension slot is initialized with JSContextExtensionObject.
966 eval("var y = 98;");
967 try {
968 throw 'Exception';
969 } catch (e) {
970 with({n:10}) {
971 debugger;
972 }
973 }
974};
975
976listener_delegate = function(exec_state) {
977 CheckScopeChain([debug.ScopeType.With,
978 debug.ScopeType.Catch,
979 debug.ScopeType.Local,
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400980 debug.ScopeType.Script,
Steve Blocka7e24c12009-10-30 11:49:00 +0000981 debug.ScopeType.Global], exec_state);
982 CheckScopeContent({n:10}, 0, exec_state);
983 CheckScopeContent({e:'Exception'}, 1, exec_state);
984 CheckScopeContent({y:98}, 2, exec_state);
Ben Murdoch257744e2011-11-30 15:57:28 +0000985};
986catch_block_4();
Steve Blocka7e24c12009-10-30 11:49:00 +0000987EndTest();
988
989
Ben Murdoch589d6972011-11-30 16:04:58 +0000990// Test catch in global scope.
991BeginTest("Catch block 5");
992listener_delegate = function(exec_state) {
993 CheckScopeChain([debug.ScopeType.Catch,
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400994 debug.ScopeType.Script,
Ben Murdoch589d6972011-11-30 16:04:58 +0000995 debug.ScopeType.Global], exec_state);
996 CheckScopeContent({e:'Exception'}, 0, exec_state);
997};
998
999try {
1000 throw 'Exception';
1001} catch (e) {
1002 debugger;
1003}
1004
1005EndTest();
1006
1007
1008// Closure inside catch in global code.
1009BeginTest("Catch block 6");
1010listener_delegate = function(exec_state) {
1011 CheckScopeChain([debug.ScopeType.Local,
1012 debug.ScopeType.Catch,
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001013 debug.ScopeType.Script,
Ben Murdoch589d6972011-11-30 16:04:58 +00001014 debug.ScopeType.Global], exec_state);
1015 CheckScopeContent({x: 2}, 0, exec_state);
1016 CheckScopeContent({e:'Exception'}, 1, exec_state);
1017};
1018
1019try {
1020 throw 'Exception';
1021} catch (e) {
1022 (function(x) {
1023 debugger;
1024 })(2);
1025}
1026EndTest();
1027
1028
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001029// Catch block in function that is marked for optimization while being executed.
1030BeginTest("Catch block 7");
1031function catch_block_7() {
1032 %OptimizeFunctionOnNextCall(catch_block_7);
1033 try {
1034 throw 'Exception';
1035 } catch (e) {
1036 debugger;
1037 }
1038};
1039
1040
1041listener_delegate = function(exec_state) {
1042 CheckScopeChain([debug.ScopeType.Catch,
1043 debug.ScopeType.Local,
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001044 debug.ScopeType.Script,
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001045 debug.ScopeType.Global], exec_state);
1046 CheckScopeContent({e:'Exception'}, 0, exec_state);
1047};
1048catch_block_7();
1049EndTest();
1050
1051
Ben Murdoch257744e2011-11-30 15:57:28 +00001052assertEquals(begin_test_count, break_count,
1053 'one or more tests did not enter the debugger');
1054assertEquals(begin_test_count, end_test_count,
1055 'one or more tests did not have its result checked');