Merge V8 5.3.332.45.  DO NOT MERGE

Test: Manual

FPIIM-449

Change-Id: Id3254828b068abdea3cb10442e0172a8c9a98e03
(cherry picked from commit 13e2dadd00298019ed862f2b2fc5068bba730bcf)
diff --git a/test/mjsunit/harmony/async-function-debug-evaluate.js b/test/mjsunit/harmony/async-function-debug-evaluate.js
new file mode 100644
index 0000000..edf7bca
--- /dev/null
+++ b/test/mjsunit/harmony/async-function-debug-evaluate.js
@@ -0,0 +1,139 @@
+// 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 --expose-debug-as debug
+
+var Debug = debug.Debug;
+var breakPointCount = 0;
+
+function listener(event, exec_state, event_data, data) {
+  if (event != Debug.DebugEvent.Break) return;
+  ++breakPointCount;
+  try {
+    if (breakPointCount === 1) {
+      assertEquals(
+          "inner", exec_state.frame(0).evaluate("inner").value());
+      assertThrows(() => exec_state.frame(0).evaluate("letInner").value(),
+                   ReferenceError);
+      assertThrows(() => exec_state.frame(0).evaluate("constInner").value(),
+                   ReferenceError);
+
+      assertEquals("outer", exec_state.frame(0).evaluate("outer").value());
+      assertEquals(
+          "const outer", exec_state.frame(0).evaluate("constOuter").value());
+      assertEquals(
+          "let outer", exec_state.frame(0).evaluate("letOuter").value());
+
+      assertEquals("outer", exec_state.frame(1).evaluate("outer").value());
+      assertEquals(
+          "const outer", exec_state.frame(1).evaluate("constOuter").value());
+      assertEquals(
+          "let outer", exec_state.frame(1).evaluate("letOuter").value());
+
+      assertThrows(() => exec_state.frame(0).evaluate("withVar").value(),
+                   ReferenceError);
+
+    } else if (breakPointCount === 2) {
+      assertEquals(
+          "inner", exec_state.frame(0).evaluate("inner").value());
+      assertThrows(() => exec_state.frame(0).evaluate("letInner").value(),
+                   ReferenceError);
+      assertThrows(() => exec_state.frame(0).evaluate("constInner").value(),
+                   ReferenceError);
+
+      assertEquals(57, exec_state.frame(0).evaluate("x").value());
+      assertEquals(100, exec_state.frame(0).evaluate("y").value());
+
+      // From breakPointCount === 1 and later, it's not possible to access
+      // earlier framestates.
+      assertEquals("outer", exec_state.frame(0).evaluate("outer").value());
+      assertEquals(
+          "const outer", exec_state.frame(0).evaluate("constOuter").value());
+      assertEquals(
+          "let outer", exec_state.frame(0).evaluate("letOuter").value());
+
+      exec_state.frame(0).evaluate("x = `x later(${x})`");
+      exec_state.frame(0).evaluate("y = `y later(${y})`");
+      exec_state.frame(0).evaluate("z = `ZEE`");
+
+    } else if (breakPointCount === 3) {
+      assertEquals(
+          "inner", exec_state.frame(0).evaluate("inner").value());
+      assertEquals(
+          "let inner", exec_state.frame(0).evaluate("letInner").value());
+      assertEquals(
+          "const inner", exec_state.frame(0).evaluate("constInner").value());
+
+    } else if (breakPointCount === 4) {
+      assertEquals(
+          "oop", exec_state.frame(0).evaluate("error.message").value());
+      assertEquals(
+          "Error",
+          exec_state.frame(0).evaluate("error.constructor.name").value());
+      assertEquals("floof", exec_state.frame(0).evaluate("bun").value());
+      assertThrows(() => exec_state.frame(0).evaluate("cow").value(),
+                   ReferenceError);
+
+      assertEquals("outer", exec_state.frame(0).evaluate("outer").value());
+      assertEquals(
+          "const outer", exec_state.frame(0).evaluate("constOuter").value());
+      assertEquals(
+          "let outer", exec_state.frame(0).evaluate("letOuter").value());
+    }
+  } catch (e) {
+    print(e.stack);
+    quit(1);
+  }
+}
+
+Debug.setListener(listener);
+
+var outer = "outer";
+const constOuter = "const outer";
+let letOuter = "let outer"
+
+async function thrower() {
+  return Promise.reject(new Error("oop"));
+}
+
+async function testLater() {
+  return { x: 57, y: 100 };
+}
+
+async function test() {
+  var inner = "inner";
+  debugger;
+
+  let withVar = await testLater();
+  with (withVar) {
+    debugger;
+  }
+
+  assertEquals("x later(57)", withVar.x);
+  assertEquals("y later(100)", withVar.y);
+  assertEquals(undefined, withVar.z);
+  assertEquals("ZEE", z);
+
+  let letInner = "let inner";
+  const constInner = "const inner";
+  debugger;
+
+  try {
+    await thrower();
+  } catch (error) {
+    const bun = "floof";
+    debugger;
+    let cow = "moo";
+  }
+}
+
+test().
+then(x => {
+  Debug.setListener(null);
+}).
+catch(error => {
+  print(error.stack);
+  quit(1);
+  Debug.setListener(null);
+});