Commit 6de4e210 authored by Marja Hölttä's avatar Marja Hölttä Committed by V8 LUCI CQ

[parser] Fix class variable redeclaration

ParserBase::ParseClassLiteral and BaseConsumedPreparseData::RestoreDataForScope
both declare the class variable, but the logic is so complex
that they sometimes ended up both declaring it.

This is further complicated by some of the variable values (esp.
inner_scope_calls_eval_) potentially changing in between, so we can't
just redo the same logic any more.

Forcefully make it work by making RestoreDataForScope declare the variable
iff ParseClassLiteral didn't.

Bug: chromium:1245870
Change-Id: I777fd9d78145240448fc25709d2b118977d91056
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3140596
Commit-Queue: Marja Hölttä <marja@chromium.org>
Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/main@{#76654}
parent dedd725c
......@@ -666,12 +666,13 @@ void BaseConsumedPreparseData<Data>::RestoreDataForScope(
scope->AsDeclarationScope()->RecordNeedsPrivateNameContextChainRecalc();
}
if (ShouldSaveClassVariableIndexField::decode(scope_data_flags)) {
Variable* var;
// An anonymous class whose class variable needs to be saved do not
Variable* var = scope->AsClassScope()->class_variable();
// An anonymous class whose class variable needs to be saved might not
// have the class variable created during reparse since we skip parsing
// the inner scopes that contain potential access to static private
// methods. So create it now.
if (scope->AsClassScope()->is_anonymous_class()) {
if (var == nullptr) {
DCHECK(scope->AsClassScope()->is_anonymous_class());
var = scope->AsClassScope()->DeclareClassVariable(
ast_value_factory, nullptr, kNoSourcePosition);
AstNodeFactory factory(ast_value_factory, zone);
......@@ -679,9 +680,6 @@ void BaseConsumedPreparseData<Data>::RestoreDataForScope(
factory.NewVariableDeclaration(kNoSourcePosition);
scope->declarations()->Add(declaration);
declaration->set_var(var);
} else {
var = scope->AsClassScope()->class_variable();
DCHECK_NOT_NULL(var);
}
var->set_is_used();
var->ForceContextAllocation();
......
// Copyright 2021 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.
class Outer {
test() {
return class {
static #a() { }
b = eval();
};
}
}
const obj = new Outer();
obj.test();
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