[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/+/3848960 Reviewed-by: Jaroslav Sevcik <jarin@chromium.org> Commit-Queue: Simon Zünd <szuend@chromium.org> Cr-Commit-Position: refs/heads/main@{#82640}
This commit is contained in:
parent
7e98192461
commit
85561d6616
@ -878,7 +878,8 @@ bool ScopeIterator::VisitLocals(const Visitor& visitor, Mode mode,
|
||||
current_scope_->AsDeclarationScope()->arguments() == var) {
|
||||
continue;
|
||||
}
|
||||
} else if (value->IsUndefined(isolate_) &&
|
||||
} else if (IsLexicalVariableMode(var->mode()) &&
|
||||
value->IsUndefined(isolate_) &&
|
||||
GetSourcePosition() != kNoSourcePosition &&
|
||||
GetSourcePosition() <= var->initializer_position()) {
|
||||
// Variables that are `undefined` could also mean an elided hole
|
||||
|
@ -8,3 +8,6 @@ variable y correctly reported as <value_unavailable>
|
||||
|
||||
Running test: testUnusedValueInTdz
|
||||
variable y correctly reported as <value_unavailable>
|
||||
|
||||
Running test: testVarStaysUndefined
|
||||
variable y correctly reported as <undefined>
|
||||
|
@ -38,23 +38,34 @@ function unusedValInTdz() {
|
||||
debugger;
|
||||
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) {
|
||||
if (scope.type !== 'local') continue;
|
||||
const {result: {result: variables}} =
|
||||
await Protocol.Runtime.getProperties({objectId: scope.object.objectId});
|
||||
for (const variable of variables) {
|
||||
if (variable.name !== 'y') continue;
|
||||
if ('value' in variable || 'get' in variable || 'set' in variable) {
|
||||
InspectorTest.log(
|
||||
'FAIL: variable y was expected to be reported as <value_unavailable>');
|
||||
} else {
|
||||
InspectorTest.log(
|
||||
'variable y correctly reported as <value_unavailable>');
|
||||
}
|
||||
const variable = variables.find(variable => variable.name === name);
|
||||
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) {
|
||||
InspectorTest.log(
|
||||
'FAIL: variable y was expected to be reported as <value_unavailable>');
|
||||
} else {
|
||||
InspectorTest.log(
|
||||
'variable y correctly reported as <value_unavailable>');
|
||||
}
|
||||
await Protocol.Debugger.resume();
|
||||
});
|
||||
@ -95,4 +106,24 @@ InspectorTest.runAsyncTestSuite([
|
||||
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(),
|
||||
]);
|
||||
},
|
||||
]);
|
||||
|
Loading…
Reference in New Issue
Block a user