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 // Flags: --harmony-async-await --expose-debug-as debug | |
6 | |
7 var Debug = debug.Debug; | |
8 | |
9 async function thrower() { throw 'Exception'; } | |
10 | |
11 async function test(name, func, args, handler, continuation) { | |
12 var handler_called = false; | |
13 var exception = null; | |
14 | |
15 function listener(event, exec_state, event_data, data) { | |
16 try { | |
17 if (event == Debug.DebugEvent.Break) { | |
18 handler_called = true; | |
19 handler(exec_state); | |
20 } | |
21 } catch (e) { | |
22 exception = e; | |
23 } | |
24 } | |
25 | |
26 Debug.setListener(listener); | |
27 | |
28 var result; | |
29 if (typeof func === "object") | |
30 result = await func.method.apply(func, args); | |
31 else | |
32 result = await func.apply(null, args); | |
33 | |
34 if (typeof continuation === "function") { | |
35 await continuation(result); | |
36 } | |
37 | |
38 assertTrue(handler_called, `Expected ${name} handler to be called`); | |
39 if (exception) { | |
40 exception.message = `${name} / ${exception.message}`; | |
41 print(exception.stack); | |
42 quit(1); | |
43 } | |
44 | |
45 Debug.setListener(null); | |
46 } | |
47 | |
48 async function runTests() { | |
49 | |
50 // Simple | |
51 await test( | |
52 "(AsyncFunctionExpression) Local 1", | |
53 async function() { debugger; }, [], | |
54 exec_state => { | |
55 CheckScopeChain([debug.ScopeType.Local, | |
56 debug.ScopeType.Closure, | |
57 debug.ScopeType.Script, | |
58 debug.ScopeType.Global], exec_state); | |
59 CheckScopeContent({}, 0, exec_state); | |
60 }); | |
61 | |
62 await test( | |
63 "(AsyncFunctionExpression) Local 1 --- resume normal", | |
64 async function() { let z = await 2; debugger; }, [], | |
65 exec_state => { | |
66 CheckScopeChain([debug.ScopeType.Local, | |
67 debug.ScopeType.Closure, | |
68 debug.ScopeType.Script, | |
69 debug.ScopeType.Global], exec_state); | |
70 CheckScopeContent({z: 2}, 0, exec_state); | |
71 }); | |
72 | |
73 await test( | |
74 "(AsyncFunctionExpression) Local 1 --- resume throw", | |
75 async function() { let q = await 1; | |
76 try { let z = await thrower(); } | |
77 catch (e) { debugger; } }, [], | |
78 exec_state => { | |
79 CheckScopeChain([debug.ScopeType.Catch, | |
80 debug.ScopeType.Local, | |
81 debug.ScopeType.Closure, | |
82 debug.ScopeType.Script, | |
83 debug.ScopeType.Global], exec_state); | |
84 CheckScopeContent({e: 'Exception'}, 0, exec_state); | |
85 CheckScopeContent({q: 1}, 1, exec_state); | |
86 | |
87 }); | |
88 | |
89 // Simple With Parameter | |
90 await test( | |
91 "(AsyncFunctionExpression) Local 2", | |
92 async function(a) { debugger; }, [1], | |
93 exec_state => { | |
94 CheckScopeChain([debug.ScopeType.Local, | |
95 debug.ScopeType.Closure, | |
96 debug.ScopeType.Script, | |
97 debug.ScopeType.Global], exec_state); | |
98 CheckScopeContent({ a: 1 }, 0, exec_state); | |
99 }); | |
100 | |
101 await test( | |
102 "(AsyncFunctionExpression) Local 2 --- resume normal", | |
103 async function(a) { let z = await 2; debugger; }, [1], | |
104 exec_state => { | |
105 CheckScopeChain([debug.ScopeType.Local, | |
106 debug.ScopeType.Closure, | |
107 debug.ScopeType.Script, | |
108 debug.ScopeType.Global], exec_state); | |
109 CheckScopeContent({ a: 1, z: 2 }, 0, exec_state); | |
110 }); | |
111 | |
112 await test( | |
113 "(AsyncFunctionExpression) Local 2 --- resume throw", | |
114 async function(a) { let z = await 2; | |
115 try { await thrower(); } catch (e) { debugger; } }, [1], | |
116 exec_state => { | |
117 CheckScopeChain([debug.ScopeType.Catch, | |
118 debug.ScopeType.Local, | |
119 debug.ScopeType.Closure, | |
120 debug.ScopeType.Script, | |
121 debug.ScopeType.Global], exec_state); | |
122 CheckScopeContent({ e: 'Exception' }, 0, exec_state); | |
123 CheckScopeContent({ a: 1, z: 2 }, 1, exec_state); | |
124 }); | |
125 | |
126 // Simple With Parameter and Variable | |
127 await test( | |
128 "(AsyncFunctionExpression) Local 3", | |
129 async function(a) { var b = 2; debugger; }, [1], | |
130 exec_state => { | |
131 CheckScopeChain([debug.ScopeType.Local, | |
132 debug.ScopeType.Closure, | |
133 debug.ScopeType.Script, | |
134 debug.ScopeType.Global], exec_state); | |
135 CheckScopeContent({ a: 1, b: 2 }, 0, exec_state); | |
136 }); | |
137 | |
138 await test( | |
139 "(AsyncFunctionExpression) Local 3 --- resume normal", | |
140 async function(a) { let y = await 3; var b = 2; let z = await 4; | |
141 debugger; }, [1], | |
142 exec_state => { | |
143 CheckScopeChain([debug.ScopeType.Local, | |
144 debug.ScopeType.Closure, | |
145 debug.ScopeType.Script, | |
146 debug.ScopeType.Global], exec_state); | |
147 CheckScopeContent({ a: 1, b: 2, y: 3, z: 4 }, 0, exec_state); | |
148 }); | |
149 | |
150 await test( | |
151 "(AsyncFunctionExpression) Local 3 --- resume throw", | |
152 async function(a) { let y = await 3; | |
153 try { var b = 2; let z = await thrower(); } | |
154 catch (e) { debugger; } }, [1], | |
155 exec_state => { | |
156 CheckScopeChain([debug.ScopeType.Catch, | |
157 debug.ScopeType.Local, | |
158 debug.ScopeType.Closure, | |
159 debug.ScopeType.Script, | |
160 debug.ScopeType.Global], exec_state); | |
161 CheckScopeContent({ e: 'Exception' }, 0, exec_state); | |
162 CheckScopeContent({ a: 1, b: 2, y: 3 }, 1, exec_state); | |
163 }); | |
164 | |
165 // Local scope with parameters and local variables. | |
166 await test( | |
167 "(AsyncFunctionExpression) Local 4", | |
168 async function(a, b) { var x = 3; var y = 4; debugger; }, [1, 2], | |
169 exec_state => { | |
170 CheckScopeChain([debug.ScopeType.Local, | |
171 debug.ScopeType.Closure, | |
172 debug.ScopeType.Script, | |
173 debug.ScopeType.Global], exec_state); | |
174 CheckScopeContent({a:1,b:2,x:3,y:4}, 0, exec_state); | |
175 }); | |
176 | |
177 await test( | |
178 "(AsyncFunctionExpression) Local 4 --- resume normal", | |
179 async function(a, b) { let q = await 5; var x = 3; var y = 4; | |
180 let r = await 6; debugger; }, [1, 2], | |
181 exec_state => { | |
182 CheckScopeChain([debug.ScopeType.Local, | |
183 debug.ScopeType.Closure, | |
184 debug.ScopeType.Script, | |
185 debug.ScopeType.Global], exec_state); | |
186 CheckScopeContent({a:1,b:2,x:3,y:4, q: 5, r: 6}, 0, exec_state); | |
187 }); | |
188 | |
189 await test( | |
190 "(AsyncFunctionExpression) Local 4 --- resume throw", | |
191 async function(a, b) { let q = await 5; var x = 3; var y = 4; | |
192 try { let r = await thrower(); } | |
193 catch (e) { debugger; } }, [1, 2], | |
194 exec_state => { | |
195 CheckScopeChain([debug.ScopeType.Catch, | |
196 debug.ScopeType.Local, | |
197 debug.ScopeType.Closure, | |
198 debug.ScopeType.Script, | |
199 debug.ScopeType.Global], exec_state); | |
200 CheckScopeContent({e: 'Exception'}, 0, exec_state); | |
201 CheckScopeContent({a:1,b:2,x:3,y:4, q: 5}, 1, exec_state); | |
202 }); | |
203 | |
204 // Empty local scope with use of eval. | |
205 await test( | |
206 "(AsyncFunctionExpression) Local 5", | |
207 async function() { eval(""); debugger; }, [], | |
208 exec_state => { | |
209 CheckScopeChain([debug.ScopeType.Local, | |
210 debug.ScopeType.Closure, | |
211 debug.ScopeType.Script, | |
212 debug.ScopeType.Global], exec_state); | |
213 CheckScopeContent({}, 0, exec_state); | |
214 }); | |
215 | |
216 await test( | |
217 "(AsyncFunctionExpression) Local 5 --- resume normal", | |
218 async function() { let x = await 1; eval(""); let y = await 2; | |
219 debugger; }, [], | |
220 exec_state => { | |
221 CheckScopeChain([debug.ScopeType.Local, | |
222 debug.ScopeType.Closure, | |
223 debug.ScopeType.Script, | |
224 debug.ScopeType.Global], exec_state); | |
225 CheckScopeContent({ x: 1, y: 2 }, 0, exec_state); | |
226 }); | |
227 | |
228 await test( | |
229 "(AsyncFunctionExpression) Local 5 --- resume throw", | |
230 async function() { let x = await 1; eval(""); | |
231 try { let y = await thrower(); } | |
232 catch (e) { debugger; } }, [], | |
233 exec_state => { | |
234 CheckScopeChain([debug.ScopeType.Catch, | |
235 debug.ScopeType.Local, | |
236 debug.ScopeType.Closure, | |
237 debug.ScopeType.Script, | |
238 debug.ScopeType.Global], exec_state); | |
239 CheckScopeContent({ e: 'Exception' }, 0, exec_state); | |
240 CheckScopeContent({ x: 1 }, 1, exec_state); | |
241 }); | |
242 | |
243 // Local introducing local variable using eval. | |
244 await test( | |
245 "(AsyncFunctionExpression) Local 6", | |
246 async function() { eval("var i = 5"); debugger; }, [], | |
247 exec_state => { | |
248 CheckScopeChain([debug.ScopeType.Local, | |
249 debug.ScopeType.Closure, | |
250 debug.ScopeType.Script, | |
251 debug.ScopeType.Global], exec_state); | |
252 CheckScopeContent({i:5}, 0, exec_state); | |
253 }); | |
254 | |
255 await test( | |
256 "(AsyncFunctionExpression) Local 6 --- resume normal", | |
257 async function() { let x = await 1; eval("var i = 5"); let y = await 2; | |
258 debugger; }, [], | |
259 exec_state => { | |
260 CheckScopeChain([debug.ScopeType.Local, | |
261 debug.ScopeType.Closure, | |
262 debug.ScopeType.Script, | |
263 debug.ScopeType.Global], exec_state); | |
264 CheckScopeContent({i:5, x: 1, y: 2}, 0, exec_state); | |
265 }); | |
266 | |
267 await test( | |
268 "(AsyncFunctionExpression) Local 6 --- resume throw", | |
269 async function() { let x = await 1; eval("var i = 5"); | |
270 try { let y = await thrower(); } | |
271 catch (e) { debugger; } }, [], | |
272 exec_state => { | |
273 CheckScopeChain([debug.ScopeType.Catch, | |
274 debug.ScopeType.Local, | |
275 debug.ScopeType.Closure, | |
276 debug.ScopeType.Script, | |
277 debug.ScopeType.Global], exec_state); | |
278 CheckScopeContent({e: 'Exception' }, 0, exec_state); | |
279 CheckScopeContent({i:5, x: 1}, 1, exec_state); | |
280 }); | |
281 | |
282 // Local scope with parameters, local variables and local variable introduced | |
283 // using eval. | |
284 await test( | |
285 "(AsyncFunctionExpression) Local 7", | |
286 async function(a, b) { var x = 3; var y = 4; | |
287 eval("var i = 5;"); eval("var j = 6"); | |
288 debugger; }, [1, 2], | |
289 exec_state => { | |
290 CheckScopeChain([debug.ScopeType.Local, | |
291 debug.ScopeType.Closure, | |
292 debug.ScopeType.Script, | |
293 debug.ScopeType.Global], exec_state); | |
294 CheckScopeContent({a:1,b:2,x:3,y:4,i:5,j:6}, 0, exec_state); | |
295 }); | |
296 | |
297 await test( | |
298 "(AsyncFunctionExpression) Local 7 --- resume normal", | |
299 async function(a, b) { let z = await 7; var x = 3; var y = 4; | |
300 eval("var i = 5;"); eval("var j = 6"); | |
301 let q = await 8; | |
302 debugger; }, [1, 2], | |
303 exec_state => { | |
304 CheckScopeChain([debug.ScopeType.Local, | |
305 debug.ScopeType.Closure, | |
306 debug.ScopeType.Script, | |
307 debug.ScopeType.Global], exec_state); | |
308 CheckScopeContent({a:1,b:2,x:3,y:4,i:5,j:6, z:7, q:8}, 0, exec_state); | |
309 }); | |
310 | |
311 await test( | |
312 "(AsyncFunctionExpression) Local 7 --- resume throw", | |
313 async function(a, b) { let z = await 7; var x = 3; var y = 4; | |
314 eval("var i = 5;"); eval("var j = 6"); | |
315 try { let q = await thrower(); } | |
316 catch (e) { debugger; } }, [1, 2], | |
317 exec_state => { | |
318 CheckScopeChain([debug.ScopeType.Catch, | |
319 debug.ScopeType.Local, | |
320 debug.ScopeType.Closure, | |
321 debug.ScopeType.Script, | |
322 debug.ScopeType.Global], exec_state); | |
323 CheckScopeContent({e: 'Exception'}, 0, exec_state); | |
324 //CheckScopeContent({a:1,b:2,x:3,y:4,i:5,j:6, z:7}, 1, exec_state); | |
325 }); | |
326 | |
327 // Nested empty with blocks. | |
328 await test( | |
329 "(AsyncFunctionExpression) With", | |
330 async function() { with ({}) { with ({}) { debugger; } } }, [], | |
331 exec_state => { | |
332 CheckScopeChain([debug.ScopeType.With, | |
333 debug.ScopeType.With, | |
334 debug.ScopeType.Local, | |
335 debug.ScopeType.Closure, | |
336 debug.ScopeType.Script, | |
337 debug.ScopeType.Global], exec_state); | |
338 CheckScopeContent({}, 0, exec_state); | |
339 CheckScopeContent({}, 1, exec_state); | |
340 }); | |
341 | |
342 await test( | |
343 "(AsyncFunctionExpression) With --- resume normal", | |
344 async function() { let x = await 1; with ({}) { with ({}) { | |
345 let y = await 2; debugger; } } }, [], | |
346 exec_state => { | |
347 CheckScopeChain([debug.ScopeType.Block, | |
348 debug.ScopeType.With, | |
349 debug.ScopeType.With, | |
350 debug.ScopeType.Local, | |
351 debug.ScopeType.Closure, | |
352 debug.ScopeType.Script, | |
353 debug.ScopeType.Global], exec_state); | |
354 CheckScopeContent({y:2}, 0, exec_state); | |
355 CheckScopeContent({}, 1, exec_state); | |
356 CheckScopeContent({}, 2, exec_state); | |
357 CheckScopeContent({x:1}, 3, exec_state); | |
358 }); | |
359 | |
360 await test( | |
361 "(AsyncFunctionExpression) With --- resume throw", | |
362 async function() { let x = await 1; with ({}) { with ({}) { | |
363 try { let y = await thrower(); } | |
364 catch (e) { debugger; } } } }, [], | |
365 exec_state => { | |
366 CheckScopeChain([debug.ScopeType.Catch, | |
367 debug.ScopeType.With, | |
368 debug.ScopeType.With, | |
369 debug.ScopeType.Local, | |
370 debug.ScopeType.Closure, | |
371 debug.ScopeType.Script, | |
372 debug.ScopeType.Global], exec_state); | |
373 CheckScopeContent({ e: 'Exception'}, 0, exec_state); | |
374 CheckScopeContent({}, 1, exec_state); | |
375 CheckScopeContent({}, 2, exec_state); | |
376 CheckScopeContent({x:1}, 3, exec_state); | |
377 }); | |
378 | |
379 // Simple closure formed by returning an inner function referering the outer | |
380 // functions arguments. | |
381 await test( | |
382 "(AsyncFunctionExpression) Closure 1", | |
383 async function(a) { return function() { debugger; return a; } }, [1], | |
384 exec_state => { | |
385 CheckScopeChain([debug.ScopeType.Local, | |
386 debug.ScopeType.Closure, | |
387 debug.ScopeType.Closure, | |
388 debug.ScopeType.Script, | |
389 debug.ScopeType.Global], exec_state); | |
390 CheckScopeContent({a:1}, 1, exec_state); | |
391 }, | |
392 result => result()); | |
393 | |
394 await test( | |
395 "(AsyncFunctionExpression) Closure 1 --- resume normal", | |
396 async function(a) { let x = await 2; | |
397 return function() { debugger; return a; } }, [1], | |
398 exec_state => { | |
399 CheckScopeChain([debug.ScopeType.Local, | |
400 debug.ScopeType.Closure, | |
401 debug.ScopeType.Closure, | |
402 debug.ScopeType.Script, | |
403 debug.ScopeType.Global], exec_state); | |
404 CheckScopeContent({a:1, x: 2}, 1, exec_state); | |
405 }, | |
406 result => result()); | |
407 | |
408 await test( | |
409 "(AsyncFunctionExpression) Closure 1 --- resume throw", | |
410 async function(a) { let x = await 2; | |
411 return async function() { | |
412 try { await thrower(); } | |
413 catch (e) { debugger; } return a; }; }, [1], | |
414 exec_state => { | |
415 CheckScopeChain([debug.ScopeType.Catch, | |
416 debug.ScopeType.Local, | |
417 debug.ScopeType.Closure, | |
418 debug.ScopeType.Closure, | |
419 debug.ScopeType.Script, | |
420 debug.ScopeType.Global], exec_state); | |
421 CheckScopeContent({e: 'Exception'}, 0, exec_state); | |
422 CheckScopeContent({a:1, x: 2}, 2, exec_state); | |
423 }, | |
424 result => result()); | |
425 | |
426 await test( | |
427 "(AsyncFunctionExpression) Catch block 1", | |
428 async function() { try { throw 'Exception'; } catch (e) { debugger; } }, [], | |
429 exec_state => { | |
430 CheckScopeChain([debug.ScopeType.Catch, | |
431 debug.ScopeType.Local, | |
432 debug.ScopeType.Closure, | |
433 debug.ScopeType.Script, | |
434 debug.ScopeType.Global], exec_state); | |
435 CheckScopeContent({e:'Exception'}, 0, exec_state); | |
436 }); | |
437 | |
438 await test( | |
439 "(AsyncFunctionExpression) Catch block 1 --- resume normal", | |
440 async function() { | |
441 let x = await 1; | |
442 try { throw 'Exception'; } catch (e) { let y = await 2; debugger; } }, [], | |
443 exec_state => { | |
444 CheckScopeChain([debug.ScopeType.Block, | |
445 debug.ScopeType.Catch, | |
446 debug.ScopeType.Local, | |
447 debug.ScopeType.Closure, | |
448 debug.ScopeType.Script, | |
449 debug.ScopeType.Global], exec_state); | |
450 CheckScopeContent({y: 2}, 0, exec_state); | |
451 CheckScopeContent({e:'Exception'}, 1, exec_state); | |
452 CheckScopeContent({x: 1}, 2, exec_state); | |
453 }); | |
454 | |
455 await test( | |
456 "(AsyncFunctionExpression) Catch block 1 --- resume throw", | |
457 async function() { | |
458 let x = await 1; | |
459 try { throw 'Exception!'; } catch (e) { | |
460 try { let y = await thrower(); } catch (e) { debugger; } } }, [], | |
461 exec_state => { | |
462 CheckScopeChain([debug.ScopeType.Catch, | |
463 debug.ScopeType.Catch, | |
464 debug.ScopeType.Local, | |
465 debug.ScopeType.Closure, | |
466 debug.ScopeType.Script, | |
467 debug.ScopeType.Global], exec_state); | |
468 CheckScopeContent({e:'Exception'}, 0, exec_state); | |
469 CheckScopeContent({e:'Exception!'}, 1, exec_state); | |
470 CheckScopeContent({x: 1}, 2, exec_state); | |
471 }); | |
472 } | |
473 | |
474 runTests().catch(error => { | |
475 print(error.stack); | |
476 quit(1); | |
477 }) | |
478 | |
479 // Check that two scope are the same. | |
480 function assertScopeMirrorEquals(scope1, scope2) { | |
481 assertEquals(scope1.scopeType(), scope2.scopeType()); | |
482 assertEquals(scope1.frameIndex(), scope2.frameIndex()); | |
483 assertEquals(scope1.scopeIndex(), scope2.scopeIndex()); | |
484 assertPropertiesEqual( | |
485 scope1.scopeObject().value(), scope2.scopeObject().value()); | |
486 } | |
487 | |
488 function CheckFastAllScopes(scopes, exec_state) { | |
489 var fast_all_scopes = exec_state.frame().allScopes(true); | |
490 var length = fast_all_scopes.length; | |
491 assertTrue(scopes.length >= length); | |
492 for (var i = 0; i < scopes.length && i < length; i++) { | |
493 var scope = fast_all_scopes[length - i - 1]; | |
494 assertTrue(scope.isScope()); | |
495 assertEquals(scopes[scopes.length - i - 1], scope.scopeType()); | |
496 } | |
497 } | |
498 | |
499 // Check that the scope chain contains the expected types of scopes. | |
500 function CheckScopeChain(scopes, exec_state) { | |
501 var all_scopes = exec_state.frame().allScopes(); | |
502 assertEquals( | |
503 scopes.length, all_scopes.length, "FrameMirror.allScopes length"); | |
504 for (var i = 0; i < scopes.length; i++) { | |
505 var scope = exec_state.frame().scope(i); | |
506 assertTrue(scope.isScope()); | |
507 assertEquals(scopes[i], scope.scopeType()); | |
508 assertScopeMirrorEquals(all_scopes[i], scope); | |
509 | |
510 // Check the global object when hitting the global scope. | |
511 if (scopes[i] == debug.ScopeType.Global) { | |
512 // Objects don't have same class (one is "global", other is "Object", | |
513 // so just check the properties directly. | |
514 assertPropertiesEqual(this, scope.scopeObject().value()); | |
515 } | |
516 } | |
517 CheckFastAllScopes(scopes, exec_state); | |
518 } | |
519 | |
520 // Check that the content of the scope is as expected. For functions just check | |
521 // that there is a function. | |
522 function CheckScopeContent(content, number, exec_state) { | |
523 var scope = exec_state.frame().scope(number); | |
524 var count = 0; | |
525 for (var p in content) { | |
526 var property_mirror = scope.scopeObject().property(p); | |
527 assertFalse(property_mirror.isUndefined(), | |
528 `property ${p} not found in scope`); | |
529 if (typeof(content[p]) === 'function') { | |
530 assertTrue(property_mirror.value().isFunction()); | |
531 } else { | |
532 assertEquals(content[p], property_mirror.value().value(), | |
533 `property ${p} has unexpected value`); | |
534 } | |
535 count++; | |
536 } | |
537 | |
538 // 'arguments' and might be exposed in the local and closure scope. Just | |
539 // ignore this. | |
540 var scope_size = scope.scopeObject().properties().length; | |
541 if (!scope.scopeObject().property('arguments').isUndefined()) { | |
542 scope_size--; | |
543 } | |
544 // Skip property with empty name. | |
545 if (!scope.scopeObject().property('').isUndefined()) { | |
546 scope_size--; | |
547 } | |
548 | |
549 if (count != scope_size) { | |
550 print('Names found in scope:'); | |
551 var names = scope.scopeObject().propertyNames(); | |
552 for (var i = 0; i < names.length; i++) { | |
553 print(names[i]); | |
554 } | |
555 } | |
556 assertEquals(count, scope_size); | |
557 } | |
OLD | NEW |