diff options
Diffstat (limited to 'deps/v8/test/debugger/debug/harmony')
19 files changed, 1140 insertions, 0 deletions
diff --git a/deps/v8/test/debugger/debug/harmony/async-debug-basic.js b/deps/v8/test/debugger/debug/harmony/async-debug-basic.js new file mode 100644 index 0000000000..c22662c01b --- /dev/null +++ b/deps/v8/test/debugger/debug/harmony/async-debug-basic.js @@ -0,0 +1,39 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-async-await + +Debug = debug.Debug + +listenerComplete = false; +breakPointCount = 0; + +async function f() { + await (async function() { var a = "a"; await 1; debugger; })(); + + var b = "b"; + + assertTrue(listenerDone); + assertFalse(exception); + assertEquals(1, breakpointCount); +} + +function listener(event, exec_state, event_data, data) { + try { + if (event != Debug.DebugEvent.Break) return; + + breakpointCount++; + listenerDone = true; + assertEquals("a", exec_state.frame(0).evaluate("a")); + assertEquals("b", exec_state.frame(1).evaluate("b")); + assertEquals("c", exec_state.frame(2).evaluate("c")); + } catch (e) { + exception = e; + }; +}; + +Debug.setListener(listener); + +var c = "c"; +f(); diff --git a/deps/v8/test/debugger/debug/harmony/async-debug-caught-exception-cases.js b/deps/v8/test/debugger/debug/harmony/async-debug-caught-exception-cases.js new file mode 100644 index 0000000000..99dc515bc2 --- /dev/null +++ b/deps/v8/test/debugger/debug/harmony/async-debug-caught-exception-cases.js @@ -0,0 +1,216 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-async-await + +Debug = debug.Debug + +let events = 0; + +function listener(event, exec_state, event_data, data) { + if (event != Debug.DebugEvent.Exception) return; + events++; +} + +async function thrower() { + throw "a"; // Exception a +} + +var reject = () => Promise.reject("b"); // Exception b + +async function awaitReturn() { await 1; return; } + +async function scalar() { return 1; } + +function nothing() { return 1; } + +function rejectConstructor() { + return new Promise((resolve, reject) => reject("c")); // Exception c +} + +async function argThrower(x = (() => { throw "d"; })()) { } // Exception d + +async function awaitThrow() { + await undefined; + throw "e"; // Exception e +} + +function constructorThrow() { + return new Promise((resolve, reject) => + Promise.resolve().then(() => + reject("f") // Exception f + ) + ); +} + +function suppressThrow() { + return thrower(); +} + +async function caught(producer) { + try { + await producer(); + } catch (e) { + } +} + +async function uncaught(producer) { + await producer(); +} + +async function indirectUncaught(producer) { + await uncaught(producer); +} + +async function indirectCaught(producer) { + try { + await uncaught(producer); + } catch (e) { + } +} + +function dotCatch(producer) { + Promise.resolve(producer()).catch(() => {}); +} + +function indirectReturnDotCatch(producer) { + (async() => producer())().catch(() => {}); +} + +function indirectAwaitDotCatch(producer) { + (async() => await producer())().catch(() => {}); +} + +function nestedDotCatch(producer) { + Promise.resolve(producer()).then().catch(() => {}); +} + +async function indirectAwaitCatch(producer) { + try { + await (() => producer())(); + } catch (e) { + } +} + +function switchCatch(producer) { + let resolve; + let promise = new Promise(r => resolve = r); + async function localCaught() { + try { + await promise; // force switching to localUncaught and back + await producer(); + } catch (e) { } + } + async function localUncaught() { + await undefined; + resolve(); + } + localCaught(); + localUncaught(); +} + +function switchDotCatch(producer) { + let resolve; + let promise = new Promise(r => resolve = r); + async function localCaught() { + await promise; // force switching to localUncaught and back + await producer(); + } + async function localUncaught() { + await undefined; + resolve(); + } + localCaught().catch(() => {}); + localUncaught(); +} + +let catches = [caught, + indirectCaught, + indirectAwaitCatch, + switchCatch, + switchDotCatch]; +let noncatches = [uncaught, indirectUncaught]; +let lateCatches = [dotCatch, + indirectReturnDotCatch, + indirectAwaitDotCatch, + nestedDotCatch]; + +let throws = [thrower, reject, argThrower, suppressThrow]; +let nonthrows = [awaitReturn, scalar, nothing]; +let lateThrows = [awaitThrow, constructorThrow]; +let uncatchable = [rejectConstructor]; + +let cases = []; + +for (let producer of throws.concat(lateThrows)) { + for (let consumer of catches) { + cases.push({ producer, consumer, expectedEvents: 1, caught: true }); + cases.push({ producer, consumer, expectedEvents: 0, caught: false }); + } +} + +for (let producer of throws.concat(lateThrows)) { + for (let consumer of noncatches) { + cases.push({ producer, consumer, expectedEvents: 1, caught: true }); + cases.push({ producer, consumer, expectedEvents: 1, caught: false }); + } +} + +for (let producer of nonthrows) { + for (let consumer of catches.concat(noncatches, lateCatches)) { + cases.push({ producer, consumer, expectedEvents: 0, caught: true }); + cases.push({ producer, consumer, expectedEvents: 0, caught: false }); + } +} + +for (let producer of uncatchable) { + for (let consumer of catches.concat(noncatches, lateCatches)) { + cases.push({ producer, consumer, expectedEvents: 1, caught: true }); + cases.push({ producer, consumer, expectedEvents: 1, caught: false }); + } +} + +for (let producer of lateThrows) { + for (let consumer of lateCatches) { + cases.push({ producer, consumer, expectedEvents: 1, caught: true }); + cases.push({ producer, consumer, expectedEvents: 0, caught: false }); + } +} + +for (let producer of throws) { + for (let consumer of lateCatches) { + cases.push({ producer, consumer, expectedEvents: 1, caught: true }); + cases.push({ producer, consumer, expectedEvents: 1, caught: false }); + } +} + + +function runPart(n) { + let subcases = cases.slice(n * cases.length / 4, + ((n + 1) * cases.length) / 4); + for (let {producer, consumer, expectedEvents, caught} of subcases) { + Debug.setListener(listener); + if (caught) { + Debug.setBreakOnException(); + } else { + Debug.setBreakOnUncaughtException(); + } + + events = 0; + consumer(producer); + %RunMicrotasks(); + + Debug.setListener(null); + if (caught) { + Debug.clearBreakOnException(); + } else { + Debug.clearBreakOnUncaughtException(); + } + if (expectedEvents != events) { + print(`producer ${producer} consumer ${consumer} expectedEvents ` + + `${expectedEvents} caught ${caught} events ${events}`); + quit(1); + } + } +} diff --git a/deps/v8/test/debugger/debug/harmony/async-debug-caught-exception-cases0.js b/deps/v8/test/debugger/debug/harmony/async-debug-caught-exception-cases0.js new file mode 100644 index 0000000000..6862e54a12 --- /dev/null +++ b/deps/v8/test/debugger/debug/harmony/async-debug-caught-exception-cases0.js @@ -0,0 +1,8 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-async-await +// Files: test/debugger/debug/harmony/async-debug-caught-exception-cases.js + +runPart(0); diff --git a/deps/v8/test/debugger/debug/harmony/async-debug-caught-exception-cases1.js b/deps/v8/test/debugger/debug/harmony/async-debug-caught-exception-cases1.js new file mode 100644 index 0000000000..17b534e8c1 --- /dev/null +++ b/deps/v8/test/debugger/debug/harmony/async-debug-caught-exception-cases1.js @@ -0,0 +1,8 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-async-await +// Files: test/debugger/debug/harmony/async-debug-caught-exception-cases.js + +runPart(1); diff --git a/deps/v8/test/debugger/debug/harmony/async-debug-caught-exception-cases2.js b/deps/v8/test/debugger/debug/harmony/async-debug-caught-exception-cases2.js new file mode 100644 index 0000000000..06583494a7 --- /dev/null +++ b/deps/v8/test/debugger/debug/harmony/async-debug-caught-exception-cases2.js @@ -0,0 +1,8 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-async-await +// Files: test/debugger/debug/harmony/async-debug-caught-exception-cases.js + +runPart(2); diff --git a/deps/v8/test/debugger/debug/harmony/async-debug-caught-exception-cases3.js b/deps/v8/test/debugger/debug/harmony/async-debug-caught-exception-cases3.js new file mode 100644 index 0000000000..451f8b9636 --- /dev/null +++ b/deps/v8/test/debugger/debug/harmony/async-debug-caught-exception-cases3.js @@ -0,0 +1,8 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-async-await +// Files: test/debugger/debug/harmony/async-debug-caught-exception-cases.js + +runPart(3); diff --git a/deps/v8/test/debugger/debug/harmony/async-debug-caught-exception.js b/deps/v8/test/debugger/debug/harmony/async-debug-caught-exception.js new file mode 100644 index 0000000000..391a41cd15 --- /dev/null +++ b/deps/v8/test/debugger/debug/harmony/async-debug-caught-exception.js @@ -0,0 +1,144 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-async-await + +Debug = debug.Debug + +var exception = null; +var log; + +function listener(event, exec_state, event_data, data) { + if (event != Debug.DebugEvent.Exception) return; + try { + var line = exec_state.frame(0).sourceLineText(); + var match = /Exception (\w)/.exec(line); + assertNotNull(match); + log.push(match[1]); + } catch (e) { + exception = e; + } +} + +async function thrower() { + throw "a"; // Exception a +} + +async function caught_throw() { + try { + await thrower(); + } catch (e) { + assertEquals("a", e); + } +} + + +// Caught throw, events on any exception. +log = []; +Debug.setListener(listener); +Debug.setBreakOnException(); +caught_throw(); +%RunMicrotasks(); +Debug.setListener(null); +Debug.clearBreakOnException(); +assertEquals(["a"], log); +assertNull(exception); + +// Caught throw, events on uncaught exception. +log = []; +Debug.setListener(listener); +Debug.setBreakOnUncaughtException(); +caught_throw(); +%RunMicrotasks(); +Debug.setListener(null); +Debug.clearBreakOnUncaughtException(); +assertEquals([], log); +assertNull(exception); + +var reject = Promise.reject("b"); + +async function caught_reject() { + try { + await reject; + } catch (e) { + assertEquals("b", e); + } +} + +// Caught reject, events on any exception. +log = []; +Debug.setListener(listener); +Debug.setBreakOnException(); +caught_reject(); +%RunMicrotasks(); +Debug.setListener(null); +Debug.clearBreakOnException(); +assertEquals([], log); +assertNull(exception); + +// Caught reject, events on uncaught exception. +log = []; +Debug.setListener(listener); +Debug.setBreakOnUncaughtException(); +caught_reject(); +%RunMicrotasks(); +Debug.setListener(null); +Debug.clearBreakOnUncaughtException(); +assertEquals([], log); +assertNull(exception); + +log = []; +Debug.setListener(listener); +Debug.setBreakOnException(); + +// "rethrown" uncaught exceptions in return don't cause another event +async function propagate_inner() { return thrower(); } +async function propagate_outer() { return propagate_inner(); } + +propagate_outer(); +%RunMicrotasks(); +assertEquals(["a"], log); +assertNull(exception); + +// Also don't propagate if an await interceded +log = []; +async function propagate_await() { await 1; return thrower(); } +async function propagate_await_outer() { return propagate_await(); } +propagate_await_outer(); +%RunMicrotasks(); +assertEquals(["a"], log); +assertNull(exception); + +Debug.clearBreakOnException(); +Debug.setBreakOnUncaughtException(); + +log = []; +Promise.resolve().then(() => Promise.reject()).catch(() => log.push("d")); // Exception c +%RunMicrotasks(); +assertEquals(["d"], log); +assertNull(exception); + +Debug.clearBreakOnUncaughtException(); +Debug.setListener(null); + +// If devtools is turned on in the middle, then catch prediction +// could be wrong (here, it mispredicts the exception as caught), +// but shouldn't crash. + +log = []; + +var resolve; +var turnOnListenerPromise = new Promise(r => resolve = r); +async function confused() { + await turnOnListenerPromise; + throw foo +} +confused(); +Promise.resolve().then(() => { + Debug.setListener(listener); + Debug.setBreakOnUncaughtException(); + resolve(); +}); + +assertEquals([], log); diff --git a/deps/v8/test/debugger/debug/harmony/async-debug-step-abort-at-break.js b/deps/v8/test/debugger/debug/harmony/async-debug-step-abort-at-break.js new file mode 100644 index 0000000000..d57db4e4e1 --- /dev/null +++ b/deps/v8/test/debugger/debug/harmony/async-debug-step-abort-at-break.js @@ -0,0 +1,55 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-async-await + +var Debug = debug.Debug; +var step_count = 0; + +function listener(event, execState, eventData, data) { + if (event != Debug.DebugEvent.Break) return; + try { + var line = execState.frame(0).sourceLineText(); + print(line); + var [match, expected_count, step] = /\/\/ B(\d) (\w+)$/.exec(line); + assertEquals(step_count++, parseInt(expected_count)); + if (step != "Continue") execState.prepareStep(Debug.StepAction[step]); + } catch (e) { + print(e, e.stack); + quit(1); + } +} + +Debug.setListener(listener); + +var late_resolve; + +function g() { + return new Promise( // B3 StepOut + function(res, rej) { + late_resolve = res; + } + ); +} + +async function f() { + var a = 1; + debugger; // B0 StepNext + a += // B1 StepNext + await // B4 StepNext + g(); // B2 StepIn + return a; +} + +f(); + +// Starting a new step action at an intermediate break point +// means that we will abort the current async step. +debugger; // B5 StepNext + +late_resolve(3); // B6 Continue + +%RunMicrotasks(); + +assertEquals(7, step_count); diff --git a/deps/v8/test/debugger/debug/harmony/async-debug-step-continue-at-break.js b/deps/v8/test/debugger/debug/harmony/async-debug-step-continue-at-break.js new file mode 100644 index 0000000000..3ae5656738 --- /dev/null +++ b/deps/v8/test/debugger/debug/harmony/async-debug-step-continue-at-break.js @@ -0,0 +1,55 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-async-await + +var Debug = debug.Debug; +var step_count = 0; + +function listener(event, execState, eventData, data) { + if (event != Debug.DebugEvent.Break) return; + try { + var line = execState.frame(0).sourceLineText(); + print(line); + var [match, expected_count, step] = /\/\/ B(\d) (\w+)$/.exec(line); + assertEquals(step_count++, parseInt(expected_count)); + if (step != "Continue") execState.prepareStep(Debug.StepAction[step]); + } catch (e) { + print(e, e.stack); + quit(1); + } +} + +Debug.setListener(listener); + +var late_resolve; + +function g() { + return new Promise( // B3 StepOut + function(res, rej) { + late_resolve = res; + } + ); +} + +async function f() { + var a = 1; + debugger; // B0 StepNext + a += // B1 StepNext + await // B4 StepNext + g(); // B2 StepIn + return a; // B6 StepNext +} // B7 Continue + +f(); + +// Continuing at an intermediate break point means that we will +// carry on with the current async step. +debugger; // B5 Continue + +late_resolve(3); + +%RunMicrotasks(); + +assertEquals(8, step_count); diff --git a/deps/v8/test/debugger/debug/harmony/async-debug-step-in-and-out.js b/deps/v8/test/debugger/debug/harmony/async-debug-step-in-and-out.js new file mode 100644 index 0000000000..388fa721cf --- /dev/null +++ b/deps/v8/test/debugger/debug/harmony/async-debug-step-in-and-out.js @@ -0,0 +1,51 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-async-await + +var Debug = debug.Debug; +var step_count = 0; + +function listener(event, execState, eventData, data) { + if (event != Debug.DebugEvent.Break) return; + try { + var line = execState.frame(0).sourceLineText(); + print(line); + var [match, expected_count, step] = /\/\/ B(\d) (\w+)$/.exec(line); + assertEquals(step_count++, parseInt(expected_count)); + if (step != "Continue") execState.prepareStep(Debug.StepAction[step]); + } catch (e) { + print(e, e.stack); + quit(1); + } +} + +Debug.setListener(listener); + +var late_resolve; + +function g() { + return new Promise( // B3 StepOut + function(res, rej) { + late_resolve = res; + } + ); +} + +async function f() { + var a = 1; + debugger; // B0 StepNext + a += // B1 StepNext + await // B4 StepNext + g(); // B2 StepIn + return a; // B5 StepNext +} // B6 Continue + +f(); + +late_resolve(3); + +%RunMicrotasks(); + +assertEquals(7, step_count); diff --git a/deps/v8/test/debugger/debug/harmony/async-debug-step-in-out-out.js b/deps/v8/test/debugger/debug/harmony/async-debug-step-in-out-out.js new file mode 100644 index 0000000000..09e3c6bf5e --- /dev/null +++ b/deps/v8/test/debugger/debug/harmony/async-debug-step-in-out-out.js @@ -0,0 +1,51 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-async-await + +var Debug = debug.Debug; +var step_count = 0; + +function listener(event, execState, eventData, data) { + if (event != Debug.DebugEvent.Break) return; + try { + var line = execState.frame(0).sourceLineText(); + print(line); + var [match, expected_count, step] = /\/\/ B(\d) (\w+)$/.exec(line); + assertEquals(step_count++, parseInt(expected_count)); + if (step != "Continue") execState.prepareStep(Debug.StepAction[step]); + } catch (e) { + print(e, e.stack); + quit(1); + } +} + +Debug.setListener(listener); + +var late_resolve; + +function g() { + return new Promise( // B3 StepOut + function(res, rej) { + late_resolve = res; + } + ); +} + +async function f() { + var a = 1; + debugger; // B0 StepNext + a += // B1 StepNext + await // B4 StepOut + g(); // B2 StepIn + return a; +} + +f(); + +late_resolve(3); // B5 Continue + +%RunMicrotasks(); + +assertEquals(6, step_count); diff --git a/deps/v8/test/debugger/debug/harmony/async-debug-step-in.js b/deps/v8/test/debugger/debug/harmony/async-debug-step-in.js new file mode 100644 index 0000000000..64366a84d3 --- /dev/null +++ b/deps/v8/test/debugger/debug/harmony/async-debug-step-in.js @@ -0,0 +1,51 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-async-await + +var Debug = debug.Debug; +var step_count = 0; + +function listener(event, execState, eventData, data) { + if (event != Debug.DebugEvent.Break) return; + try { + var line = execState.frame(0).sourceLineText(); + print(line); + var [match, expected_count, step] = /\/\/ B(\d) (\w+)$/.exec(line); + assertEquals(step_count++, parseInt(expected_count)); + if (step != "Continue") execState.prepareStep(Debug.StepAction[step]); + } catch (e) { + print(e, e.stack); + quit(1); + } +} + +Debug.setListener(listener); + +var late_resolve; + +function g() { + return new Promise( // B3 StepIn + function(res, rej) { + late_resolve = res; // B4 StepIn + } // B5 StepIn + ); +} // B6 StepIn + +async function f() { + var a = 1; + debugger; // B0 StepNext + a += // B1 StepIn + await // B7 StepIn + g(); // B2 StepIn + return a; // B8 StepIn +} // B9 Continue + +f().then(value => assertEquals(4, value)); + +late_resolve(3); + +%RunMicrotasks(); + +assertEquals(10, step_count); diff --git a/deps/v8/test/debugger/debug/harmony/async-debug-step-nested.js b/deps/v8/test/debugger/debug/harmony/async-debug-step-nested.js new file mode 100644 index 0000000000..9736195b46 --- /dev/null +++ b/deps/v8/test/debugger/debug/harmony/async-debug-step-nested.js @@ -0,0 +1,58 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-async-await + +var Debug = debug.Debug; +var step_count = 0; + +function listener(event, execState, eventData, data) { + if (event != Debug.DebugEvent.Break) return; + try { + var line = execState.frame(0).sourceLineText(); + print(line); + var [match, expected_count, step] = /\/\/ B(\d) (\w+)$/.exec(line); + assertEquals(step_count++, parseInt(expected_count)); + if (step != "Continue") execState.prepareStep(Debug.StepAction[step]); + } catch (e) { + print(e, e.stack); + quit(1); + } +} + +Debug.setListener(listener); + +var late_resolve; + +function g() { + return new Promise( // B4 StepOut + function(res, rej) { + late_resolve = res; + } + ); +} + +async function f1() { + var a = 1; + debugger; // B0 StepNext + a += // B1 StepNext + await // B6 StepNext + f2(); // B2 StepIn + return a; // B7 StepNext +} // B8 Continue + +async function f2() { + var b = + await // B5 StepOut + g(); // B3 StepIn + return b; +} + +f1(); + +late_resolve(3); + +%RunMicrotasks(); + +assertEquals(9, step_count); diff --git a/deps/v8/test/debugger/debug/harmony/async-debug-step-next-constant.js b/deps/v8/test/debugger/debug/harmony/async-debug-step-next-constant.js new file mode 100644 index 0000000000..d342790d7e --- /dev/null +++ b/deps/v8/test/debugger/debug/harmony/async-debug-step-next-constant.js @@ -0,0 +1,39 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-async-await + +var Debug = debug.Debug; +var step_count = 0; + +function listener(event, execState, eventData, data) { + if (event != Debug.DebugEvent.Break) return; + try { + var line = execState.frame(0).sourceLineText(); + print(line); + var [match, expected_count, step] = /\/\/ B(\d) (\w+)$/.exec(line); + assertEquals(step_count++, parseInt(expected_count)); + if (step != "Continue") execState.prepareStep(Debug.StepAction[step]); + } catch (e) { + print(e, e.stack); + quit(1); + } +} + +Debug.setListener(listener); + +async function f() { + var a = 1; + debugger; // B0 StepNext + a += // B1 StepNext + await // B3 StepNext + 5; // B2 StepNext + return a; // B4 StepNext +} // B5 Continue + +f(); + +%RunMicrotasks(); + +assertEquals(6, step_count); diff --git a/deps/v8/test/debugger/debug/harmony/async-debug-step-next.js b/deps/v8/test/debugger/debug/harmony/async-debug-step-next.js new file mode 100644 index 0000000000..59133eb46e --- /dev/null +++ b/deps/v8/test/debugger/debug/harmony/async-debug-step-next.js @@ -0,0 +1,51 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-async-await + +var Debug = debug.Debug; +var step_count = 0; + +function listener(event, execState, eventData, data) { + if (event != Debug.DebugEvent.Break) return; + try { + var line = execState.frame(0).sourceLineText(); + print(line); + var [match, expected_count, step] = /\/\/ B(\d) (\w+)$/.exec(line); + assertEquals(step_count++, parseInt(expected_count)); + if (step != "Continue") execState.prepareStep(Debug.StepAction[step]); + } catch (e) { + print(e, e.stack); + quit(1); + } +} + +Debug.setListener(listener); + +var late_resolve; + +function g() { + return new Promise( + function(res, rej) { + late_resolve = res; + } + ); +} + +async function f() { + var a = 1; + debugger; // B0 StepNext + a += // B1 StepNext + await // B3 StepNext + g(); // B2 StepNext + return a; // B4 StepNext +} // B5 Continue + +f(); + +late_resolve(3); + +%RunMicrotasks(); + +assertEquals(6, step_count); diff --git a/deps/v8/test/debugger/debug/harmony/async-debug-step-out.js b/deps/v8/test/debugger/debug/harmony/async-debug-step-out.js new file mode 100644 index 0000000000..b675523123 --- /dev/null +++ b/deps/v8/test/debugger/debug/harmony/async-debug-step-out.js @@ -0,0 +1,49 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-async-await + +var Debug = debug.Debug; +var step_count = 0; + +function listener(event, execState, eventData, data) { + if (event != Debug.DebugEvent.Break) return; + try { + var line = execState.frame(0).sourceLineText(); + print(line); + var [match, expected_count, step] = /\/\/ B(\d) (\w+)$/.exec(line); + assertEquals(step_count++, parseInt(expected_count)); + if (step != "Continue") execState.prepareStep(Debug.StepAction[step]); + } catch (e) { + print(e, e.stack); + quit(1); + } +} + +Debug.setListener(listener); + +var late_resolve; + +function g() { + return new Promise( + function(res, rej) { + late_resolve = res; + } + ); +} + +async function f() { + var a = 1; + debugger; // B0 StepNext + a += await g(); // B1 StepOut + return a; +} + +f(); + +late_resolve(3); // B2 Continue + +%RunMicrotasks(); + +assertEquals(3, step_count); diff --git a/deps/v8/test/debugger/debug/harmony/debug-async-break-on-stack.js b/deps/v8/test/debugger/debug/harmony/debug-async-break-on-stack.js new file mode 100644 index 0000000000..5173c87ee4 --- /dev/null +++ b/deps/v8/test/debugger/debug/harmony/debug-async-break-on-stack.js @@ -0,0 +1,77 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-async-await + +var Debug = debug.Debug; + +function assertEqualsAsync(expected, run, msg) { + var actual; + var hadValue = false; + var hadError = false; + var promise = run(); + + if (typeof promise !== "object" || typeof promise.then !== "function") { + throw new MjsUnitAssertionError( + "Expected " + run.toString() + + " to return a Promise, but it returned " + promise); + } + + promise.then(function(value) { hadValue = true; actual = value; }, + function(error) { hadError = true; actual = error; }); + + assertFalse(hadValue || hadError); + + %RunMicrotasks(); + + if (hadError) throw actual; + + assertTrue( + hadValue, "Expected '" + run.toString() + "' to produce a value"); + + assertEquals(expected, actual, msg); +} + +var break_count = 0; +var exception = null; + +function listener(event, exec_state, event_data, data) { + if (event != Debug.DebugEvent.Break) return; + try { + break_count++; + var line = exec_state.frame(0).sourceLineText(); + print(line); + assertTrue(line.indexOf(`B${break_count}`) > 0); + } catch (e) { + exception = e; + } +} + + +async function g() { + setbreaks(); + throw 1; // B1 +} + +async function f() { + try { + await g(); + } catch (e) {} + return 2; // B2 +} + +function setbreaks() { + Debug.setListener(listener); + Debug.setBreakPoint(g, 2); + Debug.setBreakPoint(f, 4); +} + +f(); + +%RunMicrotasks(); + +assertEqualsAsync(2, async () => break_count); +assertEqualsAsync(null, async () => exception); + +Debug.setListener(null); diff --git a/deps/v8/test/debugger/debug/harmony/debug-async-break.js b/deps/v8/test/debugger/debug/harmony/debug-async-break.js new file mode 100644 index 0000000000..dac3474f75 --- /dev/null +++ b/deps/v8/test/debugger/debug/harmony/debug-async-break.js @@ -0,0 +1,75 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-async-await + +var Debug = debug.Debug; + +function assertEqualsAsync(expected, run, msg) { + var actual; + var hadValue = false; + var hadError = false; + var promise = run(); + + if (typeof promise !== "object" || typeof promise.then !== "function") { + throw new MjsUnitAssertionError( + "Expected " + run.toString() + + " to return a Promise, but it returned " + promise); + } + + promise.then(function(value) { hadValue = true; actual = value; }, + function(error) { hadError = true; actual = error; }); + + assertFalse(hadValue || hadError); + + %RunMicrotasks(); + + if (hadError) throw actual; + + assertTrue( + hadValue, "Expected '" + run.toString() + "' to produce a value"); + + assertEquals(expected, actual, msg); +} + +var break_count = 0; +var exception = null; + +function listener(event, exec_state, event_data, data) { + if (event != Debug.DebugEvent.Break) return; + try { + break_count++; + var line = exec_state.frame(0).sourceLineText(); + assertTrue(line.indexOf(`B${break_count}`) > 0); + } catch (e) { + exception = e; + } +} + +Debug.setListener(listener); + +async function g() { + throw 1; +} + +async function f() { + try { + await g(); // B1 + } catch (e) {} + assertEquals(2, break_count); // B2 + return 1; // B3 +} + +Debug.setBreakPoint(f, 2); +Debug.setBreakPoint(f, 4); +Debug.setBreakPoint(f, 5); + +f(); + +%RunMicrotasks(); + +assertEqualsAsync(3, async () => break_count); +assertEqualsAsync(null, async () => exception); + +Debug.setListener(null); diff --git a/deps/v8/test/debugger/debug/harmony/debug-async-function-async-task-event.js b/deps/v8/test/debugger/debug/harmony/debug-async-function-async-task-event.js new file mode 100644 index 0000000000..d5d506e153 --- /dev/null +++ b/deps/v8/test/debugger/debug/harmony/debug-async-function-async-task-event.js @@ -0,0 +1,97 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-async-await + +// The test observes the callbacks that async/await makes to the inspector +// to make accurate stack traces. The pattern is based on saving a stack once +// with enqueueRecurring and restoring it multiple times. + +// Additionally, the limited number of events is an indirect indication that +// we are not doing extra Promise processing that could be associated with memory +// leaks (v8:5380). In particular, no stacks are saved and restored for extra +// Promise handling on throwaway Promises. + +// TODO(littledan): Write a test that demonstrates that the memory leak in +// the exception case is fixed. + +Debug = debug.Debug; + +var base_id = -1; +var exception = null; +var expected = [ + 'enqueueRecurring #1', + 'willHandle #1', + 'then #1', + 'didHandle #1', + 'willHandle #1', + 'then #2', + 'cancel #1', + 'didHandle #1', +]; + +function assertLog(msg) { + print(msg); + assertTrue(expected.length > 0); + assertEquals(expected.shift(), msg); + if (!expected.length) { + Debug.setListener(null); + } +} + +function listener(event, exec_state, event_data, data) { + if (event != Debug.DebugEvent.AsyncTaskEvent) return; + try { + if ("Promise.resolve" == event_data.name()) return; + if (base_id < 0) + base_id = event_data.id(); + var id = event_data.id() - base_id + 1; + assertTrue("async function" == event_data.name()); + assertLog(event_data.type() + " #" + id); + } catch (e) { + print(e + e.stack) + exception = e; + } +} + +Debug.setListener(listener); + +var resolver; +var p = new Promise(function(resolve, reject) { + resolver = resolve; +}); + +async function main() { + await p; + assertLog("then #1"); + await undefined; + assertLog("then #2"); +} +main(); +resolver(); + +%RunMicrotasks(); + +assertNull(exception); + +Debug.clearBreakOnUncaughtException(); +Debug.setListener(null); + +var resolve; +var turnOnListenerPromise = new Promise(r => resolve = r); +async function confused() { + await turnOnListenerPromise; + throw foo +} + +confused(); + +Promise.resolve().then(() => { + Debug.setListener(listener); + Debug.setBreakOnUncaughtException(); + resolve(); +}); + +%RunMicrotasks(); +assertNull(exception); |