Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / v8 / test / mjsunit / es6 / generators-debug-scopes.js
1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // Flags: --expose-debug-as debug
6
7 var Debug = debug.Debug;
8
9 function RunTest(name, formals_and_body, args, handler, continuation) {
10   var handler_called = false;
11   var exception = null;
12
13   function listener(event, exec_state, event_data, data) {
14     try {
15       if (event == Debug.DebugEvent.Break) {
16         handler_called = true;
17         handler(exec_state);
18       }
19     } catch (e) {
20       exception = e;
21     }
22   }
23
24   function run(thunk) {
25     handler_called = false;
26     exception = null;
27
28     var res = thunk();
29     if (continuation)
30       continuation(res);
31
32     assertTrue(handler_called, "listener not called for " + name);
33     assertNull(exception, name + " / " + exception);
34   }
35
36   var fun = Function.apply(null, formals_and_body);
37   var gen = (function*(){}).constructor.apply(null, formals_and_body);
38
39   Debug.setListener(listener);
40
41   run(function () { return fun.apply(null, args) });
42   run(function () { return gen.apply(null, args).next().value });
43
44   // TODO(wingo): Uncomment after bug 2838 is fixed.
45   // Debug.setListener(null);
46 }
47
48 // Check that two scope are the same.
49 function assertScopeMirrorEquals(scope1, scope2) {
50   assertEquals(scope1.scopeType(), scope2.scopeType());
51   assertEquals(scope1.frameIndex(), scope2.frameIndex());
52   assertEquals(scope1.scopeIndex(), scope2.scopeIndex());
53   assertPropertiesEqual(scope1.scopeObject().value(), scope2.scopeObject().value());
54 }
55
56 function CheckFastAllScopes(scopes, exec_state) {
57   var fast_all_scopes = exec_state.frame().allScopes(true);
58   var length = fast_all_scopes.length;
59   assertTrue(scopes.length >= length);
60   for (var i = 0; i < scopes.length && i < length; i++) {
61     var scope = fast_all_scopes[length - i - 1];
62     assertTrue(scope.isScope());
63     assertEquals(scopes[scopes.length - i - 1], scope.scopeType());
64   }
65 }
66
67 // Check that the scope chain contains the expected types of scopes.
68 function CheckScopeChain(scopes, exec_state) {
69   var all_scopes = exec_state.frame().allScopes();
70   assertEquals(scopes.length, exec_state.frame().scopeCount());
71   assertEquals(scopes.length, all_scopes.length, "FrameMirror.allScopes length");
72   for (var i = 0; i < scopes.length; i++) {
73     var scope = exec_state.frame().scope(i);
74     assertTrue(scope.isScope());
75     assertEquals(scopes[i], scope.scopeType());
76     assertScopeMirrorEquals(all_scopes[i], scope);
77
78     // Check the global object when hitting the global scope.
79     if (scopes[i] == debug.ScopeType.Global) {
80       // Objects don't have same class (one is "global", other is "Object",
81       // so just check the properties directly.
82       assertPropertiesEqual(this, scope.scopeObject().value());
83     }
84   }
85   CheckFastAllScopes(scopes, exec_state);
86
87   // Get the debug command processor.
88   var dcp = exec_state.debugCommandProcessor("unspecified_running_state");
89
90   // Send a scopes request and check the result.
91   var json;
92   var request_json = '{"seq":0,"type":"request","command":"scopes"}';
93   var response_json = dcp.processDebugJSONRequest(request_json);
94   var response = JSON.parse(response_json);
95   assertEquals(scopes.length, response.body.scopes.length);
96   for (var i = 0; i < scopes.length; i++) {
97     assertEquals(i, response.body.scopes[i].index);
98     assertEquals(scopes[i], response.body.scopes[i].type);
99     if (scopes[i] == debug.ScopeType.Local ||
100         scopes[i] == debug.ScopeType.Closure) {
101       assertTrue(response.body.scopes[i].object.ref < 0);
102     } else {
103       assertTrue(response.body.scopes[i].object.ref >= 0);
104     }
105     var found = false;
106     for (var j = 0; j < response.refs.length && !found; j++) {
107       found = response.refs[j].handle == response.body.scopes[i].object.ref;
108     }
109     assertTrue(found, "Scope object " + response.body.scopes[i].object.ref + " not found");
110   }
111 }
112
113 // Check that the content of the scope is as expected. For functions just check
114 // that there is a function.
115 function CheckScopeContent(content, number, exec_state) {
116   var scope = exec_state.frame().scope(number);
117   var count = 0;
118   for (var p in content) {
119     var property_mirror = scope.scopeObject().property(p);
120     assertFalse(property_mirror.isUndefined(), 'property ' + p + ' not found in scope');
121     if (typeof(content[p]) === 'function') {
122       assertTrue(property_mirror.value().isFunction());
123     } else {
124       assertEquals(content[p], property_mirror.value().value(), 'property ' + p + ' has unexpected value');
125     }
126     count++;
127   }
128
129   // 'arguments' and might be exposed in the local and closure scope. Just
130   // ignore this.
131   var scope_size = scope.scopeObject().properties().length;
132   if (!scope.scopeObject().property('arguments').isUndefined()) {
133     scope_size--;
134   }
135   // Skip property with empty name.
136   if (!scope.scopeObject().property('').isUndefined()) {
137     scope_size--;
138   }
139
140   if (count != scope_size) {
141     print('Names found in scope:');
142     var names = scope.scopeObject().propertyNames();
143     for (var i = 0; i < names.length; i++) {
144       print(names[i]);
145     }
146   }
147   assertEquals(count, scope_size);
148
149   // Get the debug command processor.
150   var dcp = exec_state.debugCommandProcessor("unspecified_running_state");
151
152   // Send a scope request for information on a single scope and check the
153   // result.
154   var request_json = '{"seq":0,"type":"request","command":"scope","arguments":{"number":';
155   request_json += scope.scopeIndex();
156   request_json += '}}';
157   var response_json = dcp.processDebugJSONRequest(request_json);
158   var response = JSON.parse(response_json);
159   assertEquals(scope.scopeType(), response.body.type);
160   assertEquals(number, response.body.index);
161   if (scope.scopeType() == debug.ScopeType.Local ||
162       scope.scopeType() == debug.ScopeType.Closure) {
163     assertTrue(response.body.object.ref < 0);
164   } else {
165     assertTrue(response.body.object.ref >= 0);
166   }
167   var found = false;
168   for (var i = 0; i < response.refs.length && !found; i++) {
169     found = response.refs[i].handle == response.body.object.ref;
170   }
171   assertTrue(found, "Scope object " + response.body.object.ref + " not found");
172 }
173
174
175 // Simple empty local scope.
176 RunTest("Local 1",
177         ['debugger;'],
178         [],
179         function (exec_state) {
180           CheckScopeChain([debug.ScopeType.Local,
181                            debug.ScopeType.Global], exec_state);
182           CheckScopeContent({}, 0, exec_state);
183         });
184
185 // Local scope with a parameter.
186 RunTest("Local 2",
187         ['a', 'debugger;'],
188         [1],
189         function (exec_state) {
190           CheckScopeChain([debug.ScopeType.Local,
191                            debug.ScopeType.Global], exec_state);
192           CheckScopeContent({a:1}, 0, exec_state);
193         });
194
195 // Local scope with a parameter and a local variable.
196 RunTest("Local 3",
197         ['a', 'var x = 3; debugger;'],
198         [1],
199         function (exec_state) {
200           CheckScopeChain([debug.ScopeType.Local,
201                            debug.ScopeType.Global], exec_state);
202           CheckScopeContent({a:1,x:3}, 0, exec_state);
203         });
204
205 // Local scope with parameters and local variables.
206 RunTest("Local 4",
207         ['a', 'b', 'var x = 3; var y = 4; debugger;'],
208         [1, 2],
209         function (exec_state) {
210           CheckScopeChain([debug.ScopeType.Local,
211                            debug.ScopeType.Global], exec_state);
212           CheckScopeContent({a:1,b:2,x:3,y:4}, 0, exec_state);
213         });
214
215 // Empty local scope with use of eval.
216 RunTest("Local 5",
217         ['eval(""); debugger;'],
218         [],
219         function (exec_state) {
220           CheckScopeChain([debug.ScopeType.Local,
221                            debug.ScopeType.Global], exec_state);
222           CheckScopeContent({}, 0, exec_state);
223         });
224
225 // Local introducing local variable using eval.
226 RunTest("Local 6",
227         ['eval("var i = 5"); debugger;'],
228         [],
229         function (exec_state) {
230           CheckScopeChain([debug.ScopeType.Local,
231                            debug.ScopeType.Global], exec_state);
232           CheckScopeContent({i:5}, 0, exec_state);
233         });
234
235 // Local scope with parameters, local variables and local variable introduced
236 // using eval.
237 RunTest("Local 7",
238         ['a', 'b',
239          "var x = 3; var y = 4;\n"
240          + "eval('var i = 5'); eval ('var j = 6');\n"
241          + "debugger;"],
242         [1, 2],
243         function (exec_state) {
244           CheckScopeChain([debug.ScopeType.Local,
245                            debug.ScopeType.Global], exec_state);
246           CheckScopeContent({a:1,b:2,x:3,y:4,i:5,j:6}, 0, exec_state);
247         });
248
249 // Nested empty with blocks.
250 RunTest("With",
251         ["with ({}) { with ({}) { debugger; } }"],
252         [],
253         function (exec_state) {
254           CheckScopeChain([debug.ScopeType.With,
255                            debug.ScopeType.With,
256                            debug.ScopeType.Local,
257                            debug.ScopeType.Global], exec_state);
258           CheckScopeContent({}, 0, exec_state);
259           CheckScopeContent({}, 1, exec_state);
260         });
261
262 // Simple closure formed by returning an inner function referering the outer
263 // functions arguments.
264 RunTest("Closure 1",
265         ['a', 'return function() { debugger; return a; }'],
266         [1],
267         function (exec_state) {
268           CheckScopeChain([debug.ScopeType.Local,
269                            debug.ScopeType.Closure,
270                            debug.ScopeType.Global], exec_state);
271           CheckScopeContent({a:1}, 1, exec_state);
272         },
273        function (result) { result() });
274
275 RunTest("The full monty",
276         ['a', 'b',
277          "var x = 3;\n" +
278          "var y = 4;\n" +
279          "eval('var i = 5');\n" +
280          "eval('var j = 6');\n" +
281          "function f(a, b) {\n" +
282          "  var x = 9;\n" +
283          "  var y = 10;\n" +
284          "  eval('var i = 11');\n" +
285          "  eval('var j = 12');\n" +
286          "  with ({j:13}){\n" +
287          "    return function() {\n" +
288          "      var x = 14;\n" +
289          "      with ({a:15}) {\n" +
290          "        with ({b:16}) {\n" +
291          "          debugger;\n" +
292          "          some_global = a;\n" +
293          "          return f;\n" +
294          "        }\n" +
295          "      }\n" +
296          "    };\n" +
297          "  }\n" +
298          "}\n" +
299          "return f(a, b);"],
300         [1, 2],
301         function (exec_state) {
302           CheckScopeChain([debug.ScopeType.With,
303                            debug.ScopeType.With,
304                            debug.ScopeType.Local,
305                            debug.ScopeType.With,
306                            debug.ScopeType.Closure,
307                            debug.ScopeType.Closure,
308                            debug.ScopeType.Global], exec_state);
309           CheckScopeContent({b:16}, 0, exec_state);
310           CheckScopeContent({a:15}, 1, exec_state);
311           CheckScopeContent({x:14}, 2, exec_state);
312           CheckScopeContent({j:13}, 3, exec_state);
313           CheckScopeContent({a:1,b:2,x:9,y:10,i:11,j:12}, 4, exec_state);
314           CheckScopeContent({a:1,b:2,x:3,y:4,i:5,j:6,f:function(){}}, 5, exec_state);
315         },
316         function (result) { result() });
317
318 RunTest("Catch block 1",
319         ["try { throw 'Exception'; } catch (e) { debugger; }"],
320         [],
321         function (exec_state) {
322           CheckScopeChain([debug.ScopeType.Catch,
323                            debug.ScopeType.Local,
324                            debug.ScopeType.Global], exec_state);
325           CheckScopeContent({e:'Exception'}, 0, exec_state);
326         });