Updated V8 from git://github.com/v8/v8.git to 57f8959fb264354ba1a2e5118db512f588917061
[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 // TODO(ES6): properly activate extended mode
33 "use strict";
34
35 // Get the Debug object exposed from the debug context global object.
36 var Debug = debug.Debug;
37
38 var test_name;
39 var listener_delegate;
40 var listener_called;
41 var exception;
42 var begin_test_count = 0;
43 var end_test_count = 0;
44 var break_count = 0;
45
46
47 // Debug event listener which delegates.
48 function listener(event, exec_state, event_data, data) {
49   try {
50     if (event == Debug.DebugEvent.Break) {
51       break_count++;
52       listener_called = true;
53       listener_delegate(exec_state);
54     }
55   } catch (e) {
56     exception = e;
57   }
58 }
59
60 // Add the debug event listener.
61 Debug.setListener(listener);
62
63
64 // Initialize for a new test.
65 function BeginTest(name) {
66   test_name = name;
67   listener_delegate = null;
68   listener_called = false;
69   exception = null;
70   begin_test_count++;
71 }
72
73
74 // Check result of a test.
75 function EndTest() {
76   assertTrue(listener_called, "listerner not called for " + test_name);
77   assertNull(exception, test_name);
78   end_test_count++;
79 }
80
81 var global_object = this;
82
83 // Check that the scope chain contains the expected types of scopes.
84 function CheckScopeChain(scopes, exec_state) {
85   assertEquals(scopes.length, exec_state.frame().scopeCount());
86   for (var i = 0; i < scopes.length; i++) {
87     var scope = exec_state.frame().scope(i);
88     assertTrue(scope.isScope());
89     assertEquals(scopes[i], scope.scopeType());
90
91     // Check the global object when hitting the global scope.
92     if (scopes[i] == debug.ScopeType.Global) {
93       // Objects don't have same class (one is "global", other is "Object",
94       // so just check the properties directly.
95       assertPropertiesEqual(global_object, scope.scopeObject().value());
96     }
97   }
98
99   // Get the debug command processor.
100   var dcp = exec_state.debugCommandProcessor("unspecified_running_state");
101
102   // Send a scopes request and check the result.
103   var json;
104   var request_json = '{"seq":0,"type":"request","command":"scopes"}';
105   var response_json = dcp.processDebugJSONRequest(request_json);
106   var response = JSON.parse(response_json);
107   assertEquals(scopes.length, response.body.scopes.length);
108   for (var i = 0; i < scopes.length; i++) {
109     assertEquals(i, response.body.scopes[i].index);
110     assertEquals(scopes[i], response.body.scopes[i].type);
111     if (scopes[i] == debug.ScopeType.Local ||
112         scopes[i] == debug.ScopeType.Closure) {
113       assertTrue(response.body.scopes[i].object.ref < 0);
114     } else {
115       assertTrue(response.body.scopes[i].object.ref >= 0);
116     }
117     var found = false;
118     for (var j = 0; j < response.refs.length && !found; j++) {
119       found = response.refs[j].handle == response.body.scopes[i].object.ref;
120     }
121     assertTrue(found, "Scope object " + response.body.scopes[i].object.ref + " not found");
122   }
123 }
124
125 // Check that the content of the scope is as expected. For functions just check
126 // that there is a function.
127 function CheckScopeContent(content, number, exec_state) {
128   var scope = exec_state.frame().scope(number);
129   var count = 0;
130   for (var p in content) {
131     var property_mirror = scope.scopeObject().property(p);
132     if (property_mirror.isUndefined()) {
133       print('property ' + p + ' not found in scope');
134     }
135     assertFalse(property_mirror.isUndefined(), 'property ' + p + ' not found in scope');
136     if (typeof(content[p]) === 'function') {
137       assertTrue(property_mirror.value().isFunction());
138     } else {
139       assertEquals(content[p], property_mirror.value().value(), 'property ' + p + ' has unexpected value');
140     }
141     count++;
142   }
143
144   // 'arguments' and might be exposed in the local and closure scope. Just
145   // ignore this.
146   var scope_size = scope.scopeObject().properties().length;
147   if (!scope.scopeObject().property('arguments').isUndefined()) {
148     scope_size--;
149   }
150   // Also ignore synthetic variable from catch block.
151   if (!scope.scopeObject().property('.catch-var').isUndefined()) {
152     scope_size--;
153   }
154   // Skip property with empty name.
155   if (!scope.scopeObject().property('').isUndefined()) {
156     scope_size--;
157   }
158   // Also ignore synthetic variable from block scopes.
159   if (!scope.scopeObject().property('.block').isUndefined()) {
160     scope_size--;
161   }
162
163   if (count != scope_size) {
164     print('Names found in scope:');
165     var names = scope.scopeObject().propertyNames();
166     for (var i = 0; i < names.length; i++) {
167       print(names[i]);
168     }
169   }
170   assertEquals(count, scope_size);
171
172   // Get the debug command processor.
173   var dcp = exec_state.debugCommandProcessor("unspecified_running_state");
174
175   // Send a scope request for information on a single scope and check the
176   // result.
177   var request_json = '{"seq":0,"type":"request","command":"scope","arguments":{"number":';
178   request_json += scope.scopeIndex();
179   request_json += '}}';
180   var response_json = dcp.processDebugJSONRequest(request_json);
181   var response = JSON.parse(response_json);
182   assertEquals(scope.scopeType(), response.body.type);
183   assertEquals(number, response.body.index);
184   if (scope.scopeType() == debug.ScopeType.Local ||
185       scope.scopeType() == debug.ScopeType.Closure) {
186     assertTrue(response.body.object.ref < 0);
187   } else {
188     assertTrue(response.body.object.ref >= 0);
189   }
190   var found = false;
191   for (var i = 0; i < response.refs.length && !found; i++) {
192     found = response.refs[i].handle == response.body.object.ref;
193   }
194   assertTrue(found, "Scope object " + response.body.object.ref + " not found");
195 }
196
197
198 // Simple empty block scope in local scope.
199 BeginTest("Local block 1");
200
201 function local_block_1() {
202   {
203     debugger;
204   }
205 }
206
207 listener_delegate = function(exec_state) {
208   CheckScopeChain([debug.ScopeType.Local,
209                    debug.ScopeType.Global], exec_state);
210   CheckScopeContent({}, 0, exec_state);
211 };
212 local_block_1();
213 EndTest();
214
215
216 // Simple empty block scope in local scope with a parameter.
217 BeginTest("Local 2");
218
219 function local_2(a) {
220   {
221     debugger;
222   }
223 }
224
225 listener_delegate = function(exec_state) {
226   CheckScopeChain([debug.ScopeType.Local,
227                    debug.ScopeType.Global], exec_state);
228   CheckScopeContent({a:1}, 0, exec_state);
229 };
230 local_2(1);
231 EndTest();
232
233
234 // Local scope with a parameter and a local variable.
235 BeginTest("Local 3");
236
237 function local_3(a) {
238   let x = 3;
239   debugger;
240 }
241
242 listener_delegate = function(exec_state) {
243   CheckScopeChain([debug.ScopeType.Local,
244                    debug.ScopeType.Global], exec_state);
245   CheckScopeContent({a:1,x:3}, 0, exec_state);
246 };
247 local_3(1);
248 EndTest();
249
250
251 // Local scope with parameters and local variables.
252 BeginTest("Local 4");
253
254 function local_4(a, b) {
255   let x = 3;
256   let y = 4;
257   debugger;
258 }
259
260 listener_delegate = function(exec_state) {
261   CheckScopeChain([debug.ScopeType.Local,
262                    debug.ScopeType.Global], exec_state);
263   CheckScopeContent({a:1,b:2,x:3,y:4}, 0, exec_state);
264 };
265 local_4(1, 2);
266 EndTest();
267
268
269 // Single variable in a block scope.
270 BeginTest("Local 5");
271
272 function local_5(a) {
273   {
274     let x = 5;
275     debugger;
276   }
277 }
278
279 listener_delegate = function(exec_state) {
280   CheckScopeChain([debug.ScopeType.Block,
281                    debug.ScopeType.Local,
282                    debug.ScopeType.Global], exec_state);
283   CheckScopeContent({x:5}, 0, exec_state);
284   CheckScopeContent({a:1}, 1, exec_state);
285 };
286 local_5(1);
287 EndTest();
288
289
290 // Two variables in a block scope.
291 BeginTest("Local 6");
292
293 function local_6(a) {
294   {
295     let x = 6;
296     let y = 7;
297     debugger;
298   }
299 }
300
301 listener_delegate = function(exec_state) {
302   CheckScopeChain([debug.ScopeType.Block,
303                    debug.ScopeType.Local,
304                    debug.ScopeType.Global], exec_state);
305   CheckScopeContent({x:6,y:7}, 0, exec_state);
306   CheckScopeContent({a:1}, 1, exec_state);
307 };
308 local_6(1);
309 EndTest();
310
311
312 // Two variables in a block scope.
313 BeginTest("Local 7");
314
315 function local_7(a) {
316   {
317     {
318       let x = 8;
319       debugger;
320     }
321   }
322 }
323
324 listener_delegate = function(exec_state) {
325   CheckScopeChain([debug.ScopeType.Block,
326                    debug.ScopeType.Local,
327                    debug.ScopeType.Global], exec_state);
328   CheckScopeContent({x:8}, 0, exec_state);
329   CheckScopeContent({a:1}, 1, exec_state);
330 };
331 local_7(1);
332 EndTest();
333
334
335 // Simple closure formed by returning an inner function referering to an outer
336 // block local variable and an outer function's parameter.
337 BeginTest("Closure 1");
338
339 function closure_1(a) {
340   var x = 2;
341   let y = 3;
342   if (true) {
343     let z = 4;
344     function f() {
345       debugger;
346       return a + x + y + z;
347     };
348     return f;
349   }
350 }
351
352 listener_delegate = function(exec_state) {
353   CheckScopeChain([debug.ScopeType.Local,
354                    debug.ScopeType.Block,
355                    debug.ScopeType.Closure,
356                    debug.ScopeType.Global], exec_state);
357   CheckScopeContent({}, 0, exec_state);
358   CheckScopeContent({a:1,x:2,y:3}, 2, exec_state);
359 };
360 closure_1(1)();
361 EndTest();
362
363
364 // Simple for-in loop over the keys of an object.
365 BeginTest("For loop 1");
366
367 function for_loop_1() {
368   for (let x in {y:undefined}) {
369     debugger;
370   }
371 }
372
373 listener_delegate = function(exec_state) {
374   CheckScopeChain([debug.ScopeType.Block,
375                    debug.ScopeType.Local,
376                    debug.ScopeType.Global], exec_state);
377   CheckScopeContent({x:'y'}, 0, exec_state);
378   // The function scope contains a temporary iteration variable.
379   CheckScopeContent({x:'y'}, 1, exec_state);
380 };
381 for_loop_1();
382 EndTest();
383
384
385 // For-in loop over the keys of an object with a block scoped let variable
386 // shadowing the iteration variable.
387 BeginTest("For loop 2");
388
389 function for_loop_2() {
390   for (let x in {y:undefined}) {
391     let x = 3;
392     debugger;
393   }
394 }
395
396 listener_delegate = function(exec_state) {
397   CheckScopeChain([debug.ScopeType.Block,
398                    debug.ScopeType.Block,
399                    debug.ScopeType.Local,
400                    debug.ScopeType.Global], exec_state);
401   CheckScopeContent({x:3}, 0, exec_state);
402   CheckScopeContent({x:'y'}, 1, exec_state);
403   // The function scope contains a temporary iteration variable.
404   CheckScopeContent({x:'y'}, 2, exec_state);
405 };
406 for_loop_2();
407 EndTest();
408
409
410 // Simple for loop.
411 BeginTest("For loop 3");
412
413 function for_loop_3() {
414   for (let x = 3; x < 4; ++x) {
415     debugger;
416   }
417 }
418
419 listener_delegate = function(exec_state) {
420   CheckScopeChain([debug.ScopeType.Block,
421                    debug.ScopeType.Local,
422                    debug.ScopeType.Global], exec_state);
423   CheckScopeContent({x:3}, 0, exec_state);
424   CheckScopeContent({}, 1, exec_state);
425 };
426 for_loop_3();
427 EndTest();
428
429
430 // For loop with a block scoped let variable shadowing the iteration variable.
431 BeginTest("For loop 4");
432
433 function for_loop_4() {
434   for (let x = 3; x < 4; ++x) {
435     let x = 5;
436     debugger;
437   }
438 }
439
440 listener_delegate = function(exec_state) {
441   CheckScopeChain([debug.ScopeType.Block,
442                    debug.ScopeType.Block,
443                    debug.ScopeType.Local,
444                    debug.ScopeType.Global], exec_state);
445   CheckScopeContent({x:5}, 0, exec_state);
446   CheckScopeContent({x:3}, 1, exec_state);
447   CheckScopeContent({}, 2, exec_state);
448 };
449 for_loop_4();
450 EndTest();
451
452
453 // For loop with two variable declarations.
454 BeginTest("For loop 5");
455
456 function for_loop_5() {
457   for (let x = 3, y = 5; x < 4; ++x) {
458     debugger;
459   }
460 }
461
462 listener_delegate = function(exec_state) {
463   CheckScopeChain([debug.ScopeType.Block,
464                    debug.ScopeType.Local,
465                    debug.ScopeType.Global], exec_state);
466   CheckScopeContent({x:3,y:5}, 0, exec_state);
467   CheckScopeContent({}, 1, exec_state);
468 };
469 for_loop_5();
470 EndTest();