a957b0f424
In particular, local variables should be allocated on stack (in bytecode register), and stored/loaded to the generator object on generator suspend/resume. The CL is based on @adamk's change to scoping/parsers (https://chromium-review.googlesource.com/c/498538/), I only made the debugger cope with this change. I should note that the CL changes the scope type of suspended generators from ScopeType.Closure to ScopeType.Local. In the future we might want to introduce ScopeType.SuspendedGenerator to make the distinction explicit. Some of the changes in the tests have been made because the debugger functions do not return scopes of closed generators anymore. Generators should be allowed to throw away their internal state when they finish. BUG=v8:6368 Review-Url: https://codereview.chromium.org/2898163002 Cr-Commit-Position: refs/heads/master@{#45515}
138 lines
4.3 KiB
JavaScript
138 lines
4.3 KiB
JavaScript
// 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: --noalways-opt
|
|
|
|
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());
|
|
// Variables in TDZ have 'undefined' as their values.
|
|
assertEquals(undefined, exec_state.frame(0).evaluate("letInner").value());
|
|
assertEquals(undefined, exec_state.frame(0).evaluate("constInner").value());
|
|
|
|
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());
|
|
|
|
// Variables in TDZ have 'undefined' as their values.
|
|
assertEquals(undefined, exec_state.frame(0).evaluate("withVar").value());
|
|
|
|
} else if (breakPointCount === 2) {
|
|
assertEquals(
|
|
"inner", exec_state.frame(0).evaluate("inner").value());
|
|
// Variables in TDZ have 'undefined' as their values.
|
|
assertEquals(undefined, exec_state.frame(0).evaluate("letInner").value());
|
|
assertEquals(undefined, exec_state.frame(0).evaluate("constInner").value());
|
|
|
|
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());
|
|
// Variables in TDZ have 'undefined' as their values.
|
|
assertEquals(undefined, exec_state.frame(0).evaluate("cow").value())
|
|
|
|
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);
|
|
});
|