text: // 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 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);
  });
  