summaryrefslogtreecommitdiff
path: root/deps/v8/test/debugger/debug/harmony
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/test/debugger/debug/harmony')
-rw-r--r--deps/v8/test/debugger/debug/harmony/async-debug-basic.js39
-rw-r--r--deps/v8/test/debugger/debug/harmony/async-debug-caught-exception-cases.js216
-rw-r--r--deps/v8/test/debugger/debug/harmony/async-debug-caught-exception-cases0.js8
-rw-r--r--deps/v8/test/debugger/debug/harmony/async-debug-caught-exception-cases1.js8
-rw-r--r--deps/v8/test/debugger/debug/harmony/async-debug-caught-exception-cases2.js8
-rw-r--r--deps/v8/test/debugger/debug/harmony/async-debug-caught-exception-cases3.js8
-rw-r--r--deps/v8/test/debugger/debug/harmony/async-debug-caught-exception.js144
-rw-r--r--deps/v8/test/debugger/debug/harmony/async-debug-step-abort-at-break.js55
-rw-r--r--deps/v8/test/debugger/debug/harmony/async-debug-step-continue-at-break.js55
-rw-r--r--deps/v8/test/debugger/debug/harmony/async-debug-step-in-and-out.js51
-rw-r--r--deps/v8/test/debugger/debug/harmony/async-debug-step-in-out-out.js51
-rw-r--r--deps/v8/test/debugger/debug/harmony/async-debug-step-in.js51
-rw-r--r--deps/v8/test/debugger/debug/harmony/async-debug-step-nested.js58
-rw-r--r--deps/v8/test/debugger/debug/harmony/async-debug-step-next-constant.js39
-rw-r--r--deps/v8/test/debugger/debug/harmony/async-debug-step-next.js51
-rw-r--r--deps/v8/test/debugger/debug/harmony/async-debug-step-out.js49
-rw-r--r--deps/v8/test/debugger/debug/harmony/debug-async-break-on-stack.js77
-rw-r--r--deps/v8/test/debugger/debug/harmony/debug-async-break.js75
-rw-r--r--deps/v8/test/debugger/debug/harmony/debug-async-function-async-task-event.js97
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);