OLD | NEW |
| (Empty) |
1 // Copyright 2016 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 // MODULE | |
6 // Flags: --expose-debug-as debug --allow-natives-syntax | |
7 | |
8 // These tests are copied from mjsunit/debug-scopes.js and adapted for modules. | |
9 | |
10 | |
11 var Debug = debug.Debug; | |
12 | |
13 var test_name; | |
14 var listener_delegate; | |
15 var listener_called; | |
16 var exception; | |
17 var begin_test_count = 0; | |
18 var end_test_count = 0; | |
19 var break_count = 0; | |
20 | |
21 | |
22 // Debug event listener which delegates. | |
23 function listener(event, exec_state, event_data, data) { | |
24 try { | |
25 if (event == Debug.DebugEvent.Break) { | |
26 break_count++; | |
27 listener_called = true; | |
28 listener_delegate(exec_state); | |
29 } | |
30 } catch (e) { | |
31 exception = e; | |
32 } | |
33 } | |
34 | |
35 // Add the debug event listener. | |
36 Debug.setListener(listener); | |
37 | |
38 | |
39 // Initialize for a new test. | |
40 function BeginTest(name) { | |
41 test_name = name; | |
42 listener_delegate = null; | |
43 listener_called = false; | |
44 exception = null; | |
45 begin_test_count++; | |
46 } | |
47 | |
48 | |
49 // Check result of a test. | |
50 function EndTest() { | |
51 assertTrue(listener_called, "listener not called for " + test_name); | |
52 assertNull(exception, test_name + " / " + exception); | |
53 end_test_count++; | |
54 } | |
55 | |
56 | |
57 // Check that two scope are the same. | |
58 function assertScopeMirrorEquals(scope1, scope2) { | |
59 assertEquals(scope1.scopeType(), scope2.scopeType()); | |
60 assertEquals(scope1.frameIndex(), scope2.frameIndex()); | |
61 assertEquals(scope1.scopeIndex(), scope2.scopeIndex()); | |
62 assertPropertiesEqual(scope1.scopeObject().value(), scope2.scopeObject().value
()); | |
63 } | |
64 | |
65 function CheckFastAllScopes(scopes, exec_state) | |
66 { | |
67 var fast_all_scopes = exec_state.frame().allScopes(true); | |
68 var length = fast_all_scopes.length; | |
69 assertTrue(scopes.length >= length); | |
70 for (var i = 0; i < scopes.length && i < length; i++) { | |
71 var scope = fast_all_scopes[length - i - 1]; | |
72 assertTrue(scope.isScope()); | |
73 assertEquals(scopes[scopes.length - i - 1], scope.scopeType()); | |
74 } | |
75 } | |
76 | |
77 | |
78 // Check that the scope chain contains the expected types of scopes. | |
79 function CheckScopeChain(scopes, exec_state) { | |
80 var all_scopes = exec_state.frame().allScopes(); | |
81 assertEquals(scopes.length, exec_state.frame().scopeCount()); | |
82 assertEquals(scopes.length, all_scopes.length, "FrameMirror.allScopes length")
; | |
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 assertScopeMirrorEquals(all_scopes[i], scope); | |
88 } | |
89 CheckFastAllScopes(scopes, exec_state); | |
90 | |
91 // Get the debug command processor. | |
92 var dcp = exec_state.debugCommandProcessor("unspecified_running_state"); | |
93 | |
94 // Send a scopes request and check the result. | |
95 var json; | |
96 var request_json = '{"seq":0,"type":"request","command":"scopes"}'; | |
97 var response_json = dcp.processDebugJSONRequest(request_json); | |
98 var response = JSON.parse(response_json); | |
99 assertEquals(scopes.length, response.body.scopes.length); | |
100 for (var i = 0; i < scopes.length; i++) { | |
101 assertEquals(i, response.body.scopes[i].index); | |
102 assertEquals(scopes[i], response.body.scopes[i].type); | |
103 if (scopes[i] == debug.ScopeType.Local || | |
104 scopes[i] == debug.ScopeType.Script || | |
105 scopes[i] == debug.ScopeType.Closure) { | |
106 assertTrue(response.body.scopes[i].object.ref < 0); | |
107 } else { | |
108 assertTrue(response.body.scopes[i].object.ref >= 0); | |
109 } | |
110 var found = false; | |
111 for (var j = 0; j < response.refs.length && !found; j++) { | |
112 found = response.refs[j].handle == response.body.scopes[i].object.ref; | |
113 } | |
114 assertTrue(found, "Scope object " + response.body.scopes[i].object.ref + " n
ot found"); | |
115 } | |
116 } | |
117 | |
118 | |
119 // Check that the scope chain contains the expected names of scopes. | |
120 function CheckScopeChainNames(names, exec_state) { | |
121 var all_scopes = exec_state.frame().allScopes(); | |
122 assertEquals(names.length, all_scopes.length, "FrameMirror.allScopes length"); | |
123 for (var i = 0; i < names.length; i++) { | |
124 var scope = exec_state.frame().scope(i); | |
125 assertTrue(scope.isScope()); | |
126 assertEquals(names[i], scope.details().name()) | |
127 } | |
128 } | |
129 | |
130 | |
131 // Check that the scope contains at least minimum_content. For functions just | |
132 // check that there is a function. | |
133 function CheckScopeContent(minimum_content, number, exec_state) { | |
134 var scope = exec_state.frame().scope(number); | |
135 var minimum_count = 0; | |
136 for (var p in minimum_content) { | |
137 var property_mirror = scope.scopeObject().property(p); | |
138 assertFalse(property_mirror.isUndefined(), 'property ' + p + ' not found in
scope'); | |
139 if (typeof(minimum_content[p]) === 'function') { | |
140 assertTrue(property_mirror.value().isFunction()); | |
141 } else { | |
142 assertEquals(minimum_content[p], property_mirror.value().value(), 'propert
y ' + p + ' has unexpected value'); | |
143 } | |
144 minimum_count++; | |
145 } | |
146 | |
147 // 'arguments' and might be exposed in the local and closure scope. Just | |
148 // ignore this. | |
149 var scope_size = scope.scopeObject().properties().length; | |
150 if (!scope.scopeObject().property('arguments').isUndefined()) { | |
151 scope_size--; | |
152 } | |
153 // Ditto for 'this'. | |
154 if (!scope.scopeObject().property('this').isUndefined()) { | |
155 scope_size--; | |
156 } | |
157 // Temporary variables introduced by the parser have not been materialized. | |
158 assertTrue(scope.scopeObject().property('').isUndefined()); | |
159 | |
160 if (scope_size < minimum_count) { | |
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 assertTrue(scope_size >= minimum_count); | |
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.Script || | |
183 scope.scopeType() == debug.ScopeType.Closure) { | |
184 assertTrue(response.body.object.ref < 0); | |
185 } else { | |
186 assertTrue(response.body.object.ref >= 0); | |
187 } | |
188 var found = false; | |
189 for (var i = 0; i < response.refs.length && !found; i++) { | |
190 found = response.refs[i].handle == response.body.object.ref; | |
191 } | |
192 assertTrue(found, "Scope object " + response.body.object.ref + " not found"); | |
193 } | |
194 | |
195 // Check that the scopes have positions as expected. | |
196 function CheckScopeChainPositions(positions, exec_state) { | |
197 var all_scopes = exec_state.frame().allScopes(); | |
198 assertTrue(positions.length <= all_scopes.length, "FrameMirror.allScopes lengt
h"); | |
199 for (var i = 0; i < positions.length; i++) { | |
200 var scope = exec_state.frame().scope(i); | |
201 assertTrue(scope.isScope()); | |
202 var position = positions[i]; | |
203 if (!position) | |
204 continue; | |
205 | |
206 print(`Checking position.start = ${position.start}, .end = ${position.end}`)
; | |
207 assertEquals(position.start, scope.details().startPosition()) | |
208 assertEquals(position.end, scope.details().endPosition()) | |
209 } | |
210 } | |
211 | |
212 // Simple empty local scope. | |
213 BeginTest("Local 1"); | |
214 | |
215 function local_1() { | |
216 debugger; | |
217 } | |
218 | |
219 listener_delegate = function(exec_state) { | |
220 CheckScopeChain([debug.ScopeType.Local, | |
221 debug.ScopeType.Module, | |
222 debug.ScopeType.Script, | |
223 debug.ScopeType.Global], exec_state); | |
224 CheckScopeContent({}, 0, exec_state); | |
225 }; | |
226 local_1(); | |
227 EndTest(); | |
228 | |
229 | |
230 // Local scope with a parameter. | |
231 BeginTest("Local 2"); | |
232 | |
233 function local_2(a) { | |
234 debugger; | |
235 } | |
236 | |
237 listener_delegate = function(exec_state) { | |
238 CheckScopeChain([debug.ScopeType.Local, | |
239 debug.ScopeType.Module, | |
240 debug.ScopeType.Script, | |
241 debug.ScopeType.Global], exec_state); | |
242 CheckScopeContent({a:1}, 0, exec_state); | |
243 }; | |
244 local_2(1); | |
245 EndTest(); | |
246 | |
247 | |
248 // Local scope with a parameter and a local variable. | |
249 BeginTest("Local 3"); | |
250 | |
251 function local_3(a) { | |
252 var x = 3; | |
253 debugger; | |
254 } | |
255 | |
256 listener_delegate = function(exec_state) { | |
257 CheckScopeChain([debug.ScopeType.Local, | |
258 debug.ScopeType.Module, | |
259 debug.ScopeType.Script, | |
260 debug.ScopeType.Global], exec_state); | |
261 CheckScopeContent({a:1,x:3}, 0, exec_state); | |
262 }; | |
263 local_3(1); | |
264 EndTest(); | |
265 | |
266 | |
267 // Local scope with parameters and local variables. | |
268 BeginTest("Local 4"); | |
269 | |
270 function local_4(a, b) { | |
271 var x = 3; | |
272 var y = 4; | |
273 debugger; | |
274 } | |
275 | |
276 listener_delegate = function(exec_state) { | |
277 CheckScopeChain([debug.ScopeType.Local, | |
278 debug.ScopeType.Module, | |
279 debug.ScopeType.Script, | |
280 debug.ScopeType.Global], exec_state); | |
281 CheckScopeContent({a:1,b:2,x:3,y:4}, 0, exec_state); | |
282 }; | |
283 local_4(1, 2); | |
284 EndTest(); | |
285 | |
286 | |
287 // Empty local scope with use of eval. | |
288 BeginTest("Local 5"); | |
289 | |
290 function local_5() { | |
291 eval(''); | |
292 debugger; | |
293 } | |
294 | |
295 listener_delegate = function(exec_state) { | |
296 CheckScopeChain([debug.ScopeType.Local, | |
297 debug.ScopeType.Module, | |
298 debug.ScopeType.Script, | |
299 debug.ScopeType.Global], exec_state); | |
300 CheckScopeContent({}, 0, exec_state); | |
301 }; | |
302 local_5(); | |
303 EndTest(); | |
304 | |
305 | |
306 // Local introducing local variable using eval. | |
307 BeginTest("Local 6"); | |
308 | |
309 function local_6() { | |
310 eval('var i = 5'); | |
311 debugger; | |
312 } | |
313 | |
314 listener_delegate = function(exec_state) { | |
315 CheckScopeChain([debug.ScopeType.Local, | |
316 debug.ScopeType.Module, | |
317 debug.ScopeType.Script, | |
318 debug.ScopeType.Global], exec_state); | |
319 CheckScopeContent({}, 0, exec_state); | |
320 }; | |
321 local_6(); | |
322 EndTest(); | |
323 | |
324 | |
325 // Local scope with parameters and local variables. | |
326 BeginTest("Local 7"); | |
327 | |
328 function local_7(a, b) { | |
329 var x = 3; | |
330 var y = 4; | |
331 eval('var i = 5'); | |
332 eval('var j = 6'); | |
333 debugger; | |
334 } | |
335 | |
336 listener_delegate = function(exec_state) { | |
337 CheckScopeChain([debug.ScopeType.Local, | |
338 debug.ScopeType.Module, | |
339 debug.ScopeType.Script, | |
340 debug.ScopeType.Global], exec_state); | |
341 CheckScopeContent({a:1,b:2,x:3,y:4}, 0, exec_state); | |
342 }; | |
343 local_7(1, 2); | |
344 EndTest(); | |
345 | |
346 | |
347 // Simple closure formed by returning an inner function referering the outer | |
348 // functions arguments. | |
349 BeginTest("Closure 1"); | |
350 | |
351 function closure_1(a) { | |
352 function f() { | |
353 debugger; | |
354 return a; | |
355 }; | |
356 return f; | |
357 } | |
358 | |
359 listener_delegate = function(exec_state) { | |
360 CheckScopeChain([debug.ScopeType.Local, | |
361 debug.ScopeType.Closure, | |
362 debug.ScopeType.Module, | |
363 debug.ScopeType.Script, | |
364 debug.ScopeType.Global], exec_state); | |
365 CheckScopeContent({a:1}, 1, exec_state); | |
366 CheckScopeChainNames(["f", "closure_1", undefined, undefined, undefined], exec
_state) | |
367 }; | |
368 closure_1(1)(); | |
369 EndTest(); | |
370 | |
371 | |
372 // Simple closure formed by returning an inner function referering the outer | |
373 // functions arguments. Due to VM optimizations parts of the actual closure is | |
374 // missing from the debugger information. | |
375 BeginTest("Closure 2"); | |
376 | |
377 function closure_2(a, b) { | |
378 var x = a + 2; | |
379 var y = b + 2; | |
380 function f() { | |
381 debugger; | |
382 return a + x; | |
383 }; | |
384 return f; | |
385 } | |
386 | |
387 listener_delegate = function(exec_state) { | |
388 CheckScopeChain([debug.ScopeType.Local, | |
389 debug.ScopeType.Closure, | |
390 debug.ScopeType.Module, | |
391 debug.ScopeType.Script, | |
392 debug.ScopeType.Global], exec_state); | |
393 CheckScopeContent({a:1,x:3}, 1, exec_state); | |
394 CheckScopeChainNames(["f", "closure_2", undefined, undefined, undefined], exec
_state) | |
395 }; | |
396 closure_2(1, 2)(); | |
397 EndTest(); | |
398 | |
399 | |
400 // Simple closure formed by returning an inner function referering the outer | |
401 // functions arguments. Using all arguments and locals from the outer function | |
402 // in the inner function makes these part of the debugger information on the | |
403 // closure. | |
404 BeginTest("Closure 3"); | |
405 | |
406 function closure_3(a, b) { | |
407 var x = a + 2; | |
408 var y = b + 2; | |
409 function f() { | |
410 debugger; | |
411 return a + b + x + y; | |
412 }; | |
413 return f; | |
414 } | |
415 | |
416 listener_delegate = function(exec_state) { | |
417 CheckScopeChain([debug.ScopeType.Local, | |
418 debug.ScopeType.Closure, | |
419 debug.ScopeType.Module, | |
420 debug.ScopeType.Script, | |
421 debug.ScopeType.Global], exec_state); | |
422 CheckScopeContent({a:1,b:2,x:3,y:4}, 1, exec_state); | |
423 CheckScopeChainNames(["f", "closure_3", undefined, undefined, undefined], exec
_state) | |
424 }; | |
425 closure_3(1, 2)(); | |
426 EndTest(); | |
427 | |
428 | |
429 | |
430 // Simple closure formed by returning an inner function referering the outer | |
431 // functions arguments. Using all arguments and locals from the outer function | |
432 // in the inner function makes these part of the debugger information on the | |
433 // closure. Use the inner function as well... | |
434 BeginTest("Closure 4"); | |
435 | |
436 function closure_4(a, b) { | |
437 var x = a + 2; | |
438 var y = b + 2; | |
439 function f() { | |
440 debugger; | |
441 if (f) { | |
442 return a + b + x + y; | |
443 } | |
444 }; | |
445 return f; | |
446 } | |
447 | |
448 listener_delegate = function(exec_state) { | |
449 CheckScopeChain([debug.ScopeType.Local, | |
450 debug.ScopeType.Closure, | |
451 debug.ScopeType.Module, | |
452 debug.ScopeType.Script, | |
453 debug.ScopeType.Global], exec_state); | |
454 CheckScopeContent({a:1,b:2,x:3,y:4,f:function(){}}, 1, exec_state); | |
455 CheckScopeChainNames(["f", "closure_4", undefined, undefined, undefined], exec
_state) | |
456 }; | |
457 closure_4(1, 2)(); | |
458 EndTest(); | |
459 | |
460 | |
461 | |
462 // Simple closure formed by returning an inner function referering the outer | |
463 // functions arguments. In the presence of eval all arguments and locals | |
464 // (including the inner function itself) from the outer function becomes part of | |
465 // the debugger infformation on the closure. | |
466 BeginTest("Closure 5"); | |
467 | |
468 function closure_5(a, b) { | |
469 var x = 3; | |
470 var y = 4; | |
471 function f() { | |
472 eval(''); | |
473 debugger; | |
474 return 1; | |
475 }; | |
476 return f; | |
477 } | |
478 | |
479 listener_delegate = function(exec_state) { | |
480 CheckScopeChain([debug.ScopeType.Local, | |
481 debug.ScopeType.Closure, | |
482 debug.ScopeType.Module, | |
483 debug.ScopeType.Script, | |
484 debug.ScopeType.Global], exec_state); | |
485 CheckScopeContent({a:1,b:2,x:3,y:4,f:function(){}}, 1, exec_state); | |
486 CheckScopeChainNames(["f", "closure_5", undefined, undefined, undefined], exec
_state) | |
487 }; | |
488 closure_5(1, 2)(); | |
489 EndTest(); | |
490 | |
491 | |
492 // Two closures. Due to optimizations only the parts actually used are provided | |
493 // through the debugger information. | |
494 BeginTest("Closure 6"); | |
495 let some_global; | |
496 function closure_6(a, b) { | |
497 function f(a, b) { | |
498 var x = 3; | |
499 var y = 4; | |
500 return function() { | |
501 var x = 3; | |
502 var y = 4; | |
503 debugger; | |
504 some_global = a; | |
505 return f; | |
506 }; | |
507 } | |
508 return f(a, b); | |
509 } | |
510 | |
511 listener_delegate = function(exec_state) { | |
512 CheckScopeChain([debug.ScopeType.Local, | |
513 debug.ScopeType.Closure, | |
514 debug.ScopeType.Closure, | |
515 debug.ScopeType.Module, | |
516 debug.ScopeType.Script, | |
517 debug.ScopeType.Global], exec_state); | |
518 CheckScopeContent({a:1}, 1, exec_state); | |
519 CheckScopeContent({f:function(){}}, 2, exec_state); | |
520 CheckScopeChainNames([undefined, "f", "closure_6", undefined, undefined, undef
ined], exec_state) | |
521 }; | |
522 closure_6(1, 2)(); | |
523 EndTest(); | |
524 | |
525 | |
526 // Two closures. In the presence of eval all information is provided as the | |
527 // compiler cannot determine which parts are used. | |
528 BeginTest("Closure 7"); | |
529 function closure_7(a, b) { | |
530 var x = 3; | |
531 var y = 4; | |
532 eval('var i = 5'); | |
533 eval('var j = 6'); | |
534 function f(a, b) { | |
535 var x = 3; | |
536 var y = 4; | |
537 eval('var i = 5'); | |
538 eval('var j = 6'); | |
539 return function() { | |
540 debugger; | |
541 some_global = a; | |
542 return f; | |
543 }; | |
544 } | |
545 return f(a, b); | |
546 } | |
547 | |
548 listener_delegate = function(exec_state) { | |
549 CheckScopeChain([debug.ScopeType.Local, | |
550 debug.ScopeType.Closure, | |
551 debug.ScopeType.Closure, | |
552 debug.ScopeType.Module, | |
553 debug.ScopeType.Script, | |
554 debug.ScopeType.Global], exec_state); | |
555 CheckScopeContent({}, 0, exec_state); | |
556 CheckScopeContent({a:1,b:2,x:3,y:4}, 1, exec_state); | |
557 CheckScopeContent({a:1,b:2,x:3,y:4,f:function(){}}, 2, exec_state); | |
558 CheckScopeChainNames([undefined, "f", "closure_7", undefined, undefined, undef
ined], exec_state) | |
559 }; | |
560 closure_7(1, 2)(); | |
561 EndTest(); | |
562 | |
563 | |
564 // Closure that may be optimized out. | |
565 BeginTest("Closure 8"); | |
566 function closure_8() { | |
567 (function inner(x) { | |
568 debugger; | |
569 })(2); | |
570 } | |
571 | |
572 listener_delegate = function(exec_state) { | |
573 CheckScopeChain([debug.ScopeType.Local, | |
574 debug.ScopeType.Module, | |
575 debug.ScopeType.Script, | |
576 debug.ScopeType.Global], exec_state); | |
577 CheckScopeContent({x: 2}, 0, exec_state); | |
578 CheckScopeChainNames(["inner", undefined, undefined, undefined], exec_state) | |
579 }; | |
580 closure_8(); | |
581 EndTest(); | |
582 | |
583 | |
584 BeginTest("Closure 9"); | |
585 let closure_9 = Function(' \ | |
586 eval("var y = 1;"); \ | |
587 eval("var z = 1;"); \ | |
588 (function inner(x) { \ | |
589 y++; \ | |
590 z++; \ | |
591 debugger; \ | |
592 })(2); \ | |
593 ') | |
594 | |
595 listener_delegate = function(exec_state) { | |
596 CheckScopeChain([debug.ScopeType.Local, | |
597 debug.ScopeType.Closure, | |
598 debug.ScopeType.Script, | |
599 debug.ScopeType.Global], exec_state); | |
600 CheckScopeChainNames(["inner", undefined, undefined, undefined], exec_state) | |
601 }; | |
602 closure_9(); | |
603 EndTest(); | |
604 | |
605 | |
606 // Test global scope. | |
607 BeginTest("Global"); | |
608 listener_delegate = function(exec_state) { | |
609 CheckScopeChain([debug.ScopeType.Module, debug.ScopeType.Script, debug.ScopeTy
pe.Global], exec_state); | |
610 CheckScopeChainNames([undefined, undefined, undefined], exec_state) | |
611 }; | |
612 debugger; | |
613 EndTest(); | |
614 | |
615 | |
616 BeginTest("Catch block 1"); | |
617 function catch_block_1() { | |
618 try { | |
619 throw 'Exception'; | |
620 } catch (e) { | |
621 debugger; | |
622 } | |
623 }; | |
624 | |
625 | |
626 listener_delegate = function(exec_state) { | |
627 CheckScopeChain([debug.ScopeType.Catch, | |
628 debug.ScopeType.Local, | |
629 debug.ScopeType.Module, | |
630 debug.ScopeType.Script, | |
631 debug.ScopeType.Global], exec_state); | |
632 CheckScopeContent({e:'Exception'}, 0, exec_state); | |
633 CheckScopeChainNames(["catch_block_1", "catch_block_1", undefined, undefined,
undefined], exec_state) | |
634 }; | |
635 catch_block_1(); | |
636 EndTest(); | |
637 | |
638 | |
639 BeginTest("Catch block 3"); | |
640 function catch_block_3() { | |
641 eval("var y = 78;"); | |
642 try { | |
643 throw 'Exception'; | |
644 } catch (e) { | |
645 debugger; | |
646 } | |
647 }; | |
648 | |
649 | |
650 listener_delegate = function(exec_state) { | |
651 CheckScopeChain([debug.ScopeType.Catch, | |
652 debug.ScopeType.Local, | |
653 debug.ScopeType.Module, | |
654 debug.ScopeType.Script, | |
655 debug.ScopeType.Global], exec_state); | |
656 CheckScopeContent({e:'Exception'}, 0, exec_state); | |
657 CheckScopeContent({}, 1, exec_state); | |
658 CheckScopeChainNames(["catch_block_3", "catch_block_3", undefined, undefined,
undefined], exec_state) | |
659 }; | |
660 catch_block_3(); | |
661 EndTest(); | |
662 | |
663 | |
664 // Test catch in global scope. | |
665 BeginTest("Catch block 5"); | |
666 listener_delegate = function(exec_state) { | |
667 CheckScopeChain([debug.ScopeType.Catch, | |
668 debug.ScopeType.Module, | |
669 debug.ScopeType.Script, | |
670 debug.ScopeType.Global], exec_state); | |
671 CheckScopeContent({e:'Exception'}, 0, exec_state); | |
672 CheckScopeChainNames([undefined, undefined, undefined, undefined], exec_state) | |
673 }; | |
674 | |
675 try { | |
676 throw 'Exception'; | |
677 } catch (e) { | |
678 debugger; | |
679 } | |
680 | |
681 EndTest(); | |
682 | |
683 | |
684 // Closure inside catch in global code. | |
685 BeginTest("Catch block 6"); | |
686 listener_delegate = function(exec_state) { | |
687 CheckScopeChain([debug.ScopeType.Local, | |
688 debug.ScopeType.Catch, | |
689 debug.ScopeType.Module, | |
690 debug.ScopeType.Script, | |
691 debug.ScopeType.Global], exec_state); | |
692 CheckScopeContent({x: 2}, 0, exec_state); | |
693 CheckScopeContent({e:'Exception'}, 1, exec_state); | |
694 CheckScopeChainNames([undefined, undefined, undefined, undefined, undefined],
exec_state) | |
695 }; | |
696 | |
697 try { | |
698 throw 'Exception'; | |
699 } catch (e) { | |
700 (function(x) { | |
701 debugger; | |
702 })(2); | |
703 } | |
704 EndTest(); | |
705 | |
706 | |
707 // Catch block in function that is marked for optimization while being executed. | |
708 BeginTest("Catch block 7"); | |
709 function catch_block_7() { | |
710 %OptimizeFunctionOnNextCall(catch_block_7); | |
711 try { | |
712 throw 'Exception'; | |
713 } catch (e) { | |
714 debugger; | |
715 } | |
716 }; | |
717 | |
718 | |
719 listener_delegate = function(exec_state) { | |
720 CheckScopeChain([debug.ScopeType.Catch, | |
721 debug.ScopeType.Local, | |
722 debug.ScopeType.Module, | |
723 debug.ScopeType.Script, | |
724 debug.ScopeType.Global], exec_state); | |
725 CheckScopeContent({e:'Exception'}, 0, exec_state); | |
726 CheckScopeChainNames(["catch_block_7", "catch_block_7", undefined, undefined,
undefined], exec_state) | |
727 }; | |
728 catch_block_7(); | |
729 EndTest(); | |
730 | |
731 | |
732 BeginTest("Classes and methods 1"); | |
733 | |
734 listener_delegate = function(exec_state) { | |
735 "use strict" | |
736 CheckScopeChain([debug.ScopeType.Local, | |
737 debug.ScopeType.Module, | |
738 debug.ScopeType.Script, | |
739 debug.ScopeType.Global], exec_state); | |
740 CheckScopeContent({}, 1, exec_state); | |
741 CheckScopeChainNames(["m", undefined, undefined, undefined], exec_state) | |
742 }; | |
743 | |
744 (function() { | |
745 "use strict"; | |
746 class C1 { | |
747 m() { | |
748 debugger; | |
749 } | |
750 } | |
751 new C1().m(); | |
752 })(); | |
753 | |
754 EndTest(); | |
755 | |
756 BeginTest("Scope positions"); | |
757 var code1 = "function f() { \n" + | |
758 " var a = 1; \n" + | |
759 " function b() { \n" + | |
760 " debugger; \n" + | |
761 " return a + 1; \n" + | |
762 " } \n" + | |
763 " b(); \n" + | |
764 "} \n" + | |
765 "f(); \n"; | |
766 | |
767 listener_delegate = function(exec_state) { | |
768 CheckScopeChainPositions([{start: 58, end: 118}, {start: 10, end: 162}], exec_
state); | |
769 } | |
770 eval(code1); | |
771 EndTest(); | |
772 | |
773 | |
774 BeginTest("Scope positions in for statement"); | |
775 var code3 = "function for_statement() { \n" + | |
776 " for (let i = 0; i < 1; i++) { \n" + | |
777 " debugger; \n" + | |
778 " } \n" + | |
779 "} \n" + | |
780 "for_statement(); \n"; | |
781 | |
782 listener_delegate = function(exec_state) { | |
783 CheckScopeChain([debug.ScopeType.Block, | |
784 debug.ScopeType.Local, | |
785 debug.ScopeType.Module, | |
786 debug.ScopeType.Script, | |
787 debug.ScopeType.Global], exec_state); | |
788 CheckScopeChainPositions([{start: 52, end: 111}, {start: 22, end: 145}], exec_
state); | |
789 } | |
790 eval(code3); | |
791 EndTest(); | |
792 | |
793 BeginTest("Scope positions in for statement with lexical block"); | |
794 var code4 = "function for_statement() { \n" + | |
795 " for (let i = 0; i < 1; i++) { \n" + | |
796 " let j; \n" + | |
797 " debugger; \n" + | |
798 " } \n" + | |
799 "} \n" + | |
800 "for_statement(); \n"; | |
801 | |
802 listener_delegate = function(exec_state) { | |
803 CheckScopeChain([debug.ScopeType.Block, | |
804 debug.ScopeType.Block, | |
805 debug.ScopeType.Local, | |
806 debug.ScopeType.Module, | |
807 debug.ScopeType.Script, | |
808 debug.ScopeType.Global], exec_state); | |
809 CheckScopeChainPositions([{start: 66, end: 147}, {start: 52, end: 147}, {start
: 22, end: 181}], exec_state); | |
810 } | |
811 eval(code4); | |
812 EndTest(); | |
813 | |
814 BeginTest("Scope positions in lexical for each statement"); | |
815 var code5 = "function for_each_statement() { \n" + | |
816 " for (let i of [0]) { \n" + | |
817 " debugger; \n" + | |
818 " } \n" + | |
819 "} \n" + | |
820 "for_each_statement(); \n"; | |
821 | |
822 listener_delegate = function(exec_state) { | |
823 CheckScopeChain([debug.ScopeType.Block, | |
824 debug.ScopeType.Local, | |
825 debug.ScopeType.Module, | |
826 debug.ScopeType.Script, | |
827 debug.ScopeType.Global], exec_state); | |
828 CheckScopeChainPositions([{start: 55, end: 111}, {start: 27, end: 145}], exec_
state); | |
829 } | |
830 eval(code5); | |
831 EndTest(); | |
832 | |
833 BeginTest("Scope positions in lexical for each statement with lexical block"); | |
834 var code6 = "function for_each_statement() { \n" + | |
835 " for (let i of [0]) { \n" + | |
836 " let j; \n" + | |
837 " debugger; \n" + | |
838 " } \n" + | |
839 "} \n" + | |
840 "for_each_statement(); \n"; | |
841 | |
842 listener_delegate = function(exec_state) { | |
843 CheckScopeChain([debug.ScopeType.Block, | |
844 debug.ScopeType.Block, | |
845 debug.ScopeType.Local, | |
846 debug.ScopeType.Module, | |
847 debug.ScopeType.Script, | |
848 debug.ScopeType.Global], exec_state); | |
849 CheckScopeChainPositions([{start: 57, end: 147}, {start: 55, end: 147}, {start
: 27, end: 181}], exec_state); | |
850 } | |
851 eval(code6); | |
852 EndTest(); | |
853 | |
854 BeginTest("Scope positions in non-lexical for each statement"); | |
855 var code7 = "function for_each_statement() { \n" + | |
856 " var i; \n" + | |
857 " for (i of [0]) { \n" + | |
858 " debugger; \n" + | |
859 " } \n" + | |
860 "} \n" + | |
861 "for_each_statement(); \n"; | |
862 | |
863 listener_delegate = function(exec_state) { | |
864 CheckScopeChain([debug.ScopeType.Local, | |
865 debug.ScopeType.Module, | |
866 debug.ScopeType.Script, | |
867 debug.ScopeType.Global], exec_state); | |
868 CheckScopeChainPositions([{start: 27, end: 181}], exec_state); | |
869 } | |
870 eval(code7); | |
871 EndTest(); | |
872 | |
873 BeginTest("Scope positions in non-lexical for each statement with lexical block"
); | |
874 var code8 = "function for_each_statement() { \n" + | |
875 " var i; \n" + | |
876 " for (i of [0]) { \n" + | |
877 " let j; \n" + | |
878 " debugger; \n" + | |
879 " } \n" + | |
880 "} \n" + | |
881 "for_each_statement(); \n"; | |
882 | |
883 listener_delegate = function(exec_state) { | |
884 CheckScopeChain([debug.ScopeType.Block, | |
885 debug.ScopeType.Local, | |
886 debug.ScopeType.Module, | |
887 debug.ScopeType.Script, | |
888 debug.ScopeType.Global], exec_state); | |
889 CheckScopeChainPositions([{start: 89, end: 183}, {start: 27, end: 217}], exec_
state); | |
890 } | |
891 eval(code8); | |
892 EndTest(); | |
893 | |
894 assertEquals(begin_test_count, break_count, | |
895 'one or more tests did not enter the debugger'); | |
896 assertEquals(begin_test_count, end_test_count, | |
897 'one or more tests did not have its result checked'); | |
OLD | NEW |