Commit b065411f authored by adamk's avatar adamk Committed by Commit bot

Always give class literals a block scope

Re-land of https://crrev.com/cf13dda1ba25e8293ea143f33c6c5f6233a39c86,
fixing the issue with vector stores.

Class methods always have the class scope on their scope chain in order
to implement strong mode checks. Previously, that scope wasn't attached
to the ClassLiteral for anonymous classes (since the scope contained
no bindings).

This patch simply puts that same scope on the ClassLiteral, anonymous
or not, which simplifies other code that needs to reason about the scope
of a class and its methods.

Review URL: https://codereview.chromium.org/1418433002

Cr-Commit-Position: refs/heads/master@{#31381}
parent 68a74034
...@@ -2662,7 +2662,7 @@ class ClassLiteral final : public Expression { ...@@ -2662,7 +2662,7 @@ class ClassLiteral final : public Expression {
FeedbackVectorSlotCache* cache) override; FeedbackVectorSlotCache* cache) override;
bool NeedsProxySlot() const { bool NeedsProxySlot() const {
return FLAG_vector_stores && scope() != NULL && return FLAG_vector_stores && class_variable_proxy() != nullptr &&
class_variable_proxy()->var()->IsUnallocated(); class_variable_proxy()->var()->IsUnallocated();
} }
......
...@@ -1533,20 +1533,15 @@ void AstGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) { ...@@ -1533,20 +1533,15 @@ void AstGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) {
void AstGraphBuilder::VisitClassLiteral(ClassLiteral* expr) { void AstGraphBuilder::VisitClassLiteral(ClassLiteral* expr) {
if (expr->scope() == NULL) { // Visit declarations and class literal in a block scope.
// Visit class literal in the same scope, no declarations. if (expr->scope()->ContextLocalCount() > 0) {
Node* context = BuildLocalBlockContext(expr->scope());
ContextScope scope(this, expr->scope(), context);
VisitDeclarations(expr->scope()->declarations());
VisitClassLiteralContents(expr); VisitClassLiteralContents(expr);
} else { } else {
// Visit declarations and class literal in a block scope. VisitDeclarations(expr->scope()->declarations());
if (expr->scope()->ContextLocalCount() > 0) { VisitClassLiteralContents(expr);
Node* context = BuildLocalBlockContext(expr->scope());
ContextScope scope(this, expr->scope(), context);
VisitDeclarations(expr->scope()->declarations());
VisitClassLiteralContents(expr);
} else {
VisitDeclarations(expr->scope()->declarations());
VisitClassLiteralContents(expr);
}
} }
} }
...@@ -1644,8 +1639,7 @@ void AstGraphBuilder::VisitClassLiteralContents(ClassLiteral* expr) { ...@@ -1644,8 +1639,7 @@ void AstGraphBuilder::VisitClassLiteralContents(ClassLiteral* expr) {
literal = NewNode(op, literal, proto); literal = NewNode(op, literal, proto);
// Assign to class variable. // Assign to class variable.
if (expr->scope() != NULL) { if (expr->class_variable_proxy() != nullptr) {
DCHECK_NOT_NULL(expr->class_variable_proxy());
Variable* var = expr->class_variable_proxy()->var(); Variable* var = expr->class_variable_proxy()->var();
FrameStateBeforeAndAfter states(this, BailoutId::None()); FrameStateBeforeAndAfter states(this, BailoutId::None());
VectorSlotPair feedback = CreateVectorSlotPair( VectorSlotPair feedback = CreateVectorSlotPair(
......
...@@ -1330,8 +1330,7 @@ void FullCodeGenerator::VisitClassLiteral(ClassLiteral* lit) { ...@@ -1330,8 +1330,7 @@ void FullCodeGenerator::VisitClassLiteral(ClassLiteral* lit) {
EmitClassDefineProperties(lit); EmitClassDefineProperties(lit);
if (lit->scope() != NULL) { if (lit->class_variable_proxy() != nullptr) {
DCHECK_NOT_NULL(lit->class_variable_proxy());
EmitVariableAssignment(lit->class_variable_proxy()->var(), EmitVariableAssignment(lit->class_variable_proxy()->var(),
Token::INIT_CONST, lit->ProxySlot()); Token::INIT_CONST, lit->ProxySlot());
} }
......
...@@ -4895,15 +4895,13 @@ ClassLiteral* Parser::ParseClassLiteral(const AstRawString* name, ...@@ -4895,15 +4895,13 @@ ClassLiteral* Parser::ParseClassLiteral(const AstRawString* name,
block_scope->language_mode()); block_scope->language_mode());
} }
// Note that we do not finalize this block scope because strong
// mode uses it as a sentinel value indicating an anonymous class.
block_scope->set_end_position(end_pos); block_scope->set_end_position(end_pos);
if (name != NULL) { if (name != NULL) {
DCHECK_NOT_NULL(proxy); DCHECK_NOT_NULL(proxy);
proxy->var()->set_initializer_position(end_pos); proxy->var()->set_initializer_position(end_pos);
} else {
// Unnamed classes should not have scopes (the scope will be empty).
DCHECK_EQ(block_scope->num_var_or_const(), 0);
block_scope = nullptr;
} }
return factory()->NewClassLiteral(name, block_scope, proxy, extends, return factory()->NewClassLiteral(name, block_scope, proxy, extends,
......
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