Commit 85561d66 authored by Simon Zünd's avatar Simon Zünd Committed by V8 LUCI CQ

[debug] Only apply TDZ 'value unavailable' logic for let/const

This CL refines https://crrev.com/c/3829539 to only apply to let and
const declared variables. `var`s should stay `undefined`.

R=jarin@chromium.org

Bug: chromium:1328681
Change-Id: I35778c89fb04439348a4f6aebcdeb2db6234f9d0
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3848960Reviewed-by: 's avatarJaroslav Sevcik <jarin@chromium.org>
Commit-Queue: Simon Zünd <szuend@chromium.org>
Cr-Commit-Position: refs/heads/main@{#82640}
parent 7e981924
...@@ -878,7 +878,8 @@ bool ScopeIterator::VisitLocals(const Visitor& visitor, Mode mode, ...@@ -878,7 +878,8 @@ bool ScopeIterator::VisitLocals(const Visitor& visitor, Mode mode,
current_scope_->AsDeclarationScope()->arguments() == var) { current_scope_->AsDeclarationScope()->arguments() == var) {
continue; continue;
} }
} else if (value->IsUndefined(isolate_) && } else if (IsLexicalVariableMode(var->mode()) &&
value->IsUndefined(isolate_) &&
GetSourcePosition() != kNoSourcePosition && GetSourcePosition() != kNoSourcePosition &&
GetSourcePosition() <= var->initializer_position()) { GetSourcePosition() <= var->initializer_position()) {
// Variables that are `undefined` could also mean an elided hole // Variables that are `undefined` could also mean an elided hole
......
...@@ -8,3 +8,6 @@ variable y correctly reported as <value_unavailable> ...@@ -8,3 +8,6 @@ variable y correctly reported as <value_unavailable>
Running test: testUnusedValueInTdz Running test: testUnusedValueInTdz
variable y correctly reported as <value_unavailable> variable y correctly reported as <value_unavailable>
Running test: testVarStaysUndefined
variable y correctly reported as <undefined>
...@@ -38,15 +38,28 @@ function unusedValInTdz() { ...@@ -38,15 +38,28 @@ function unusedValInTdz() {
debugger; debugger;
let y = 1; let y = 1;
} }
function varStaysUndefined() {
debugger;
var y = 42;
}
`); `);
Protocol.Debugger.onPaused(async ({params: {callFrames: [{scopeChain}]}}) => { async function findLocalVariable(name, scopeChain) {
for (const scope of scopeChain) { for (const scope of scopeChain) {
if (scope.type !== 'local') continue; if (scope.type !== 'local') continue;
const {result: {result: variables}} = const {result: {result: variables}} =
await Protocol.Runtime.getProperties({objectId: scope.object.objectId}); await Protocol.Runtime.getProperties({objectId: scope.object.objectId});
for (const variable of variables) { const variable = variables.find(variable => variable.name === name);
if (variable.name !== 'y') continue; if (!variable) {
InspectorTest.log(`FAIL: variable ${name} not found in local scope`);
}
return variable;
}
}
Protocol.Debugger.onPaused(async ({ params: { callFrames: [{ scopeChain }] } }) => {
const variable = await findLocalVariable('y', scopeChain);
if ('value' in variable || 'get' in variable || 'set' in variable) { if ('value' in variable || 'get' in variable || 'set' in variable) {
InspectorTest.log( InspectorTest.log(
'FAIL: variable y was expected to be reported as <value_unavailable>'); 'FAIL: variable y was expected to be reported as <value_unavailable>');
...@@ -54,8 +67,6 @@ Protocol.Debugger.onPaused(async ({params: {callFrames: [{scopeChain}]}}) => { ...@@ -54,8 +67,6 @@ Protocol.Debugger.onPaused(async ({params: {callFrames: [{scopeChain}]}}) => {
InspectorTest.log( InspectorTest.log(
'variable y correctly reported as <value_unavailable>'); 'variable y correctly reported as <value_unavailable>');
} }
}
}
await Protocol.Debugger.resume(); await Protocol.Debugger.resume();
}); });
...@@ -95,4 +106,24 @@ InspectorTest.runAsyncTestSuite([ ...@@ -95,4 +106,24 @@ InspectorTest.runAsyncTestSuite([
Protocol.Debugger.disable(), Protocol.Debugger.disable(),
]); ]);
}, },
async function testVarStaysUndefined() {
await Promise.all([
Protocol.Runtime.enable(),
Protocol.Debugger.enable(),
]);
Protocol.Runtime.evaluate({ expression: 'varStaysUndefined()' });
const { params: { callFrames: [{ scopeChain }] } } = await Protocol.Debugger.oncePaused();
const variable = await findLocalVariable('y', scopeChain);
if ('value' in variable && variable.value.type === 'undefined') {
InspectorTest.log('variable y correctly reported as <undefined>');
} else {
InspectorTest.log('FAIL: variable y was expected to be reported as <undefined>');
}
await Protocol.Debugger.resume();
await Promise.all([
Protocol.Runtime.disable(),
Protocol.Debugger.disable(),
]);
},
]); ]);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment