4c49d9a4b0b3e2c14bd9cdaa1ba664839b54cbc6
[profile/ivi/qtjsbackend.git] / src / 3rdparty / v8 / test / mjsunit / harmony / debug-blockscopes.js
1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 //     * Redistributions of source code must retain the above copyright
7 //       notice, this list of conditions and the following disclaimer.
8 //     * Redistributions in binary form must reproduce the above
9 //       copyright notice, this list of conditions and the following
10 //       disclaimer in the documentation and/or other materials provided
11 //       with the distribution.
12 //     * Neither the name of Google Inc. nor the names of its
13 //       contributors may be used to endorse or promote products derived
14 //       from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28 // Flags: --expose-debug-as debug --harmony-scoping
29 // The functions used for testing backtraces. They are at the top to make the
30 // testing of source line/column easier.
31
32
33 // Get the Debug object exposed from the debug context global object.
34 Debug = debug.Debug;
35
36 var test_name;
37 var listener_delegate;
38 var listener_called;
39 var exception;
40 var begin_test_count = 0;
41 var end_test_count = 0;
42 var break_count = 0;
43
44
45 // Debug event listener which delegates.
46 function listener(event, exec_state, event_data, data) {
47   try {
48     if (event == Debug.DebugEvent.Break) {
49       break_count++;
50       listener_called = true;
51       listener_delegate(exec_state);
52     }
53   } catch (e) {
54     exception = e;
55   }
56 }
57
58 // Add the debug event listener.
59 Debug.setListener(listener);
60
61
62 // Initialize for a new test.
63 function BeginTest(name) {
64   test_name = name;
65   listener_delegate = null;
66   listener_called = false;
67   exception = null;
68   begin_test_count++;
69 }
70
71
72 // Check result of a test.
73 function EndTest() {
74   assertTrue(listener_called, "listerner not called for " + test_name);
75   assertNull(exception, test_name);
76   end_test_count++;
77 }
78
79
80 // Check that the scope chain contains the expected types of scopes.
81 function CheckScopeChain(scopes, exec_state) {
82   assertEquals(scopes.length, exec_state.frame().scopeCount());
83   for (var i = 0; i < scopes.length; i++) {
84     var scope = exec_state.frame().scope(i);
85     assertTrue(scope.isScope());
86     assertEquals(scopes[i], scope.scopeType());
87
88     // Check the global object when hitting the global scope.
89     if (scopes[i] == debug.ScopeType.Global) {
90       // Objects don't have same class (one is "global", other is "Object",
91       // so just check the properties directly.
92       assertPropertiesEqual(this, scope.scopeObject().value());
93     }
94   }
95
96   // Get the debug command processor.
97   var dcp = exec_state.debugCommandProcessor("unspecified_running_state");
98
99   // Send a scopes request and check the result.
100   var json;
101   var request_json = '{"seq":0,"type":"request","command":"scopes"}';
102   var response_json = dcp.processDebugJSONRequest(request_json);
103   var response = JSON.parse(response_json);
104   assertEquals(scopes.length, response.body.scopes.length);
105   for (var i = 0; i < scopes.length; i++) {
106     assertEquals(i, response.body.scopes[i].index);
107     assertEquals(scopes[i], response.body.scopes[i].type);
108     if (scopes[i] == debug.ScopeType.Local ||
109         scopes[i] == debug.ScopeType.Closure) {
110       assertTrue(response.body.scopes[i].object.ref < 0);
111     } else {
112       assertTrue(response.body.scopes[i].object.ref >= 0);
113     }
114     var found = false;
115     for (var j = 0; j < response.refs.length && !found; j++) {
116       found = response.refs[j].handle == response.body.scopes[i].object.ref;
117     }
118     assertTrue(found, "Scope object " + response.body.scopes[i].object.ref + " not found");
119   }
120 }
121
122 // Check that the content of the scope is as expected. For functions just check
123 // that there is a function.
124 function CheckScopeContent(content, number, exec_state) {
125   var scope = exec_state.frame().scope(number);
126   var count = 0;
127   for (var p in content) {
128     var property_mirror = scope.scopeObject().property(p);
129     if (property_mirror.isUndefined()) {
130       print('property ' + p + ' not found in scope');
131     }
132     assertFalse(property_mirror.isUndefined(), 'property ' + p + ' not found in scope');
133     if (typeof(content[p]) === 'function') {
134       assertTrue(property_mirror.value().isFunction());
135     } else {
136       assertEquals(content[p], property_mirror.value().value(), 'property ' + p + ' has unexpected value');
137     }
138     count++;
139   }
140
141   // 'arguments' and might be exposed in the local and closure scope. Just
142   // ignore this.
143   var scope_size = scope.scopeObject().properties().length;
144   if (!scope.scopeObject().property('arguments').isUndefined()) {
145     scope_size--;
146   }
147   // Also ignore synthetic variable from catch block.
148   if (!scope.scopeObject().property('.catch-var').isUndefined()) {
149     scope_size--;
150   }
151   // Skip property with empty name.
152   if (!scope.scopeObject().property('').isUndefined()) {
153     scope_size--;
154   }
155   // Also ignore synthetic variable from block scopes.
156   if (!scope.scopeObject().property('.block').isUndefined()) {
157     scope_size--;
158   }
159
160   if (count != scope_size) {
161     print('Names found in scope:');
162     var names = scope.scopeObject().propertyNames();
163     for (var i = 0; i < names.length; i++) {
164       print(names[i]);
165     }
166   }
167   assertEquals(count, scope_size);
168
169   // Get the debug command processor.
170   var dcp = exec_state.debugCommandProcessor("unspecified_running_state");
171
172   // Send a scope request for information on a single scope and check the
173   // result.
174   var request_json = '{"seq":0,"type":"request","command":"scope","arguments":{"number":';
175   request_json += scope.scopeIndex();
176   request_json += '}}';
177   var response_json = dcp.processDebugJSONRequest(request_json);
178   var response = JSON.parse(response_json);
179   assertEquals(scope.scopeType(), response.body.type);
180   assertEquals(number, response.body.index);
181   if (scope.scopeType() == debug.ScopeType.Local ||
182       scope.scopeType() == debug.ScopeType.Closure) {
183     assertTrue(response.body.object.ref < 0);
184   } else {
185     assertTrue(response.body.object.ref >= 0);
186   }
187   var found = false;
188   for (var i = 0; i < response.refs.length && !found; i++) {
189     found = response.refs[i].handle == response.body.object.ref;
190   }
191   assertTrue(found, "Scope object " + response.body.object.ref + " not found");
192 }
193
194
195 // Simple empty block scope in local scope.
196 BeginTest("Local block 1");
197
198 function local_block_1() {
199   {
200     debugger;
201   }
202 }
203
204 listener_delegate = function(exec_state) {
205   CheckScopeChain([debug.ScopeType.Local,
206                    debug.ScopeType.Global], exec_state);
207   CheckScopeContent({}, 0, exec_state);
208 };
209 local_block_1();
210 EndTest();
211
212
213 // Simple empty block scope in local scope with a parameter.
214 BeginTest("Local 2");
215
216 function local_2(a) {
217   {
218     debugger;
219   }
220 }
221
222 listener_delegate = function(exec_state) {
223   CheckScopeChain([debug.ScopeType.Local,
224                    debug.ScopeType.Global], exec_state);
225   CheckScopeContent({a:1}, 0, exec_state);
226 };
227 local_2(1);
228 EndTest();
229
230
231 // Local scope with a parameter and a local variable.
232 BeginTest("Local 3");
233
234 function local_3(a) {
235   let x = 3;
236   debugger;
237 }
238
239 listener_delegate = function(exec_state) {
240   CheckScopeChain([debug.ScopeType.Local,
241                    debug.ScopeType.Global], exec_state);
242   CheckScopeContent({a:1,x:3}, 0, exec_state);
243 };
244 local_3(1);
245 EndTest();
246
247
248 // Local scope with parameters and local variables.
249 BeginTest("Local 4");
250
251 function local_4(a, b) {
252   let x = 3;
253   let y = 4;
254   debugger;
255 }
256
257 listener_delegate = function(exec_state) {
258   CheckScopeChain([debug.ScopeType.Local,
259                    debug.ScopeType.Global], exec_state);
260   CheckScopeContent({a:1,b:2,x:3,y:4}, 0, exec_state);
261 };
262 local_4(1, 2);
263 EndTest();
264
265
266 // Single variable in a block scope.
267 BeginTest("Local 5");
268
269 function local_5(a) {
270   {
271     let x = 5;
272     debugger;
273   }
274 }
275
276 listener_delegate = function(exec_state) {
277   CheckScopeChain([debug.ScopeType.Block,
278                    debug.ScopeType.Local,
279                    debug.ScopeType.Global], exec_state);
280   CheckScopeContent({x:5}, 0, exec_state);
281   CheckScopeContent({a:1}, 1, exec_state);
282 };
283 local_5(1);
284 EndTest();
285
286
287 // Two variables in a block scope.
288 BeginTest("Local 6");
289
290 function local_6(a) {
291   {
292     let x = 6;
293     let y = 7;
294     debugger;
295   }
296 }
297
298 listener_delegate = function(exec_state) {
299   CheckScopeChain([debug.ScopeType.Block,
300                    debug.ScopeType.Local,
301                    debug.ScopeType.Global], exec_state);
302   CheckScopeContent({x:6,y:7}, 0, exec_state);
303   CheckScopeContent({a:1}, 1, exec_state);
304 };
305 local_6(1);
306 EndTest();
307
308
309 // Two variables in a block scope.
310 BeginTest("Local 7");
311
312 function local_7(a) {
313   {
314     {
315       let x = 8;
316       debugger;
317     }
318   }
319 }
320
321 listener_delegate = function(exec_state) {
322   CheckScopeChain([debug.ScopeType.Block,
323                    debug.ScopeType.Local,
324                    debug.ScopeType.Global], exec_state);
325   CheckScopeContent({x:8}, 0, exec_state);
326   CheckScopeContent({a:1}, 1, exec_state);
327 };
328 local_7(1);
329 EndTest();
330
331
332 // Single empty with block.
333 BeginTest("With block 1");
334
335 function with_block_1() {
336   with({}) {
337     debugger;
338   }
339 }
340
341 listener_delegate = function(exec_state) {
342   CheckScopeChain([debug.ScopeType.With,
343                    debug.ScopeType.Local,
344                    debug.ScopeType.Global], exec_state);
345   CheckScopeContent({}, 0, exec_state);
346   CheckScopeContent({}, 1, exec_state);
347 };
348 with_block_1();
349 EndTest();
350
351
352 // Nested empty with blocks.
353 BeginTest("With block 2");
354
355 function with_block_2() {
356   with({}) {
357     with({}) {
358       debugger;
359     }
360   }
361 }
362
363 listener_delegate = function(exec_state) {
364   CheckScopeChain([debug.ScopeType.With,
365                    debug.ScopeType.With,
366                    debug.ScopeType.Local,
367                    debug.ScopeType.Global], exec_state);
368   CheckScopeContent({}, 0, exec_state);
369   CheckScopeContent({}, 1, exec_state);
370   CheckScopeContent({}, 2, exec_state);
371 };
372 with_block_2();
373 EndTest();
374
375
376 // With block using an in-place object literal.
377 BeginTest("With block 3");
378
379 function with_block_3() {
380   with({a:1,b:2}) {
381     debugger;
382   }
383 }
384
385 listener_delegate = function(exec_state) {
386   CheckScopeChain([debug.ScopeType.With,
387                    debug.ScopeType.Local,
388                    debug.ScopeType.Global], exec_state);
389   CheckScopeContent({a:1,b:2}, 0, exec_state);
390 };
391 with_block_3();
392 EndTest();
393
394
395 // Nested with blocks using in-place object literals.
396 BeginTest("With block 4");
397
398 function with_block_4() {
399   with({a:1,b:2}) {
400     with({a:2,b:1}) {
401       debugger;
402     }
403   }
404 }
405
406 listener_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({a:2,b:1}, 0, exec_state);
412   CheckScopeContent({a:1,b:2}, 1, exec_state);
413 };
414 with_block_4();
415 EndTest();
416
417
418 // With block and a block local variable.
419 BeginTest("With block 5");
420
421 function with_block_5() {
422   with({a:1}) {
423     let a = 2;
424     debugger;
425   }
426 }
427
428 listener_delegate = function(exec_state) {
429   CheckScopeChain([debug.ScopeType.Block,
430                    debug.ScopeType.With,
431                    debug.ScopeType.Local,
432                    debug.ScopeType.Global], exec_state);
433   CheckScopeContent({a:2}, 0, exec_state);
434   CheckScopeContent({a:1}, 1, exec_state);
435 };
436 with_block_5();
437 EndTest();
438
439
440 // Simple closure formed by returning an inner function referering to an outer
441 // block local variable and an outer function's parameter.
442 BeginTest("Closure 1");
443
444 function closure_1(a) {
445   var x = 2;
446   let y = 3;
447   if (true) {
448     let z = 4;
449     function f() {
450       debugger;
451       return a + x + y + z;
452     };
453     return f;
454   }
455 }
456
457 listener_delegate = function(exec_state) {
458   CheckScopeChain([debug.ScopeType.Local,
459                    debug.ScopeType.Block,
460                    debug.ScopeType.Closure,
461                    debug.ScopeType.Global], exec_state);
462   CheckScopeContent({}, 0, exec_state);
463   CheckScopeContent({a:1,x:2,y:3}, 2, exec_state);
464 };
465 closure_1(1)();
466 EndTest();
467
468
469 // Simple for-in loop over the keys of an object.
470 BeginTest("For loop 1");
471
472 function for_loop_1() {
473   for (let x in {y:undefined}) {
474     debugger;
475   }
476 }
477
478 listener_delegate = function(exec_state) {
479   CheckScopeChain([debug.ScopeType.Block,
480                    debug.ScopeType.Local,
481                    debug.ScopeType.Global], exec_state);
482   CheckScopeContent({x:'y'}, 0, exec_state);
483   // The function scope contains a temporary iteration variable.
484   CheckScopeContent({x:'y'}, 1, exec_state);
485 };
486 for_loop_1();
487 EndTest();
488
489
490 // For-in loop over the keys of an object with a block scoped let variable
491 // shadowing the iteration variable.
492 BeginTest("For loop 2");
493
494 function for_loop_2() {
495   for (let x in {y:undefined}) {
496     let x = 3;
497     debugger;
498   }
499 }
500
501 listener_delegate = function(exec_state) {
502   CheckScopeChain([debug.ScopeType.Block,
503                    debug.ScopeType.Block,
504                    debug.ScopeType.Local,
505                    debug.ScopeType.Global], exec_state);
506   CheckScopeContent({x:3}, 0, exec_state);
507   CheckScopeContent({x:'y'}, 1, exec_state);
508   // The function scope contains a temporary iteration variable.
509   CheckScopeContent({x:'y'}, 2, exec_state);
510 };
511 for_loop_2();
512 EndTest();
513
514
515 // Simple for loop.
516 BeginTest("For loop 3");
517
518 function for_loop_3() {
519   for (let x = 3; x < 4; ++x) {
520     debugger;
521   }
522 }
523
524 listener_delegate = function(exec_state) {
525   CheckScopeChain([debug.ScopeType.Block,
526                    debug.ScopeType.Local,
527                    debug.ScopeType.Global], exec_state);
528   CheckScopeContent({x:3}, 0, exec_state);
529   CheckScopeContent({}, 1, exec_state);
530 };
531 for_loop_3();
532 EndTest();
533
534
535 // For loop with a block scoped let variable shadowing the iteration variable.
536 BeginTest("For loop 4");
537
538 function for_loop_4() {
539   for (let x = 3; x < 4; ++x) {
540     let x = 5;
541     debugger;
542   }
543 }
544
545 listener_delegate = function(exec_state) {
546   CheckScopeChain([debug.ScopeType.Block,
547                    debug.ScopeType.Block,
548                    debug.ScopeType.Local,
549                    debug.ScopeType.Global], exec_state);
550   CheckScopeContent({x:5}, 0, exec_state);
551   CheckScopeContent({x:3}, 1, exec_state);
552   CheckScopeContent({}, 2, exec_state);
553 };
554 for_loop_4();
555 EndTest();
556
557
558 // For loop with two variable declarations.
559 BeginTest("For loop 5");
560
561 function for_loop_5() {
562   for (let x = 3, y = 5; x < 4; ++x) {
563     debugger;
564   }
565 }
566
567 listener_delegate = function(exec_state) {
568   CheckScopeChain([debug.ScopeType.Block,
569                    debug.ScopeType.Local,
570                    debug.ScopeType.Global], exec_state);
571   CheckScopeContent({x:3,y:5}, 0, exec_state);
572   CheckScopeContent({}, 1, exec_state);
573 };
574 for_loop_5();
575 EndTest();