From cf13dda1ba25e8293ea143f33c6c5f6233a39c86 Mon Sep 17 00:00:00 2001 From: adamk Date: Mon, 19 Oct 2015 04:38:14 -0700 Subject: [PATCH] Always give class literals a block scope 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/1413903002 Cr-Commit-Position: refs/heads/master@{#31371} --- src/compiler/ast-graph-builder.cc | 22 ++++++++-------------- src/full-codegen/full-codegen.cc | 3 +-- src/parser.cc | 6 ++---- 3 files changed, 11 insertions(+), 20 deletions(-) diff --git a/src/compiler/ast-graph-builder.cc b/src/compiler/ast-graph-builder.cc index 5b07447b62..5889e46fb3 100644 --- a/src/compiler/ast-graph-builder.cc +++ b/src/compiler/ast-graph-builder.cc @@ -1533,20 +1533,15 @@ void AstGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) { void AstGraphBuilder::VisitClassLiteral(ClassLiteral* expr) { - if (expr->scope() == NULL) { - // Visit class literal in the same scope, no declarations. + // Visit declarations and class literal in a block scope. + if (expr->scope()->ContextLocalCount() > 0) { + Node* context = BuildLocalBlockContext(expr->scope()); + ContextScope scope(this, expr->scope(), context); + VisitDeclarations(expr->scope()->declarations()); VisitClassLiteralContents(expr); } else { - // Visit declarations and class literal in a block scope. - if (expr->scope()->ContextLocalCount() > 0) { - Node* context = BuildLocalBlockContext(expr->scope()); - ContextScope scope(this, expr->scope(), context); - VisitDeclarations(expr->scope()->declarations()); - VisitClassLiteralContents(expr); - } else { - VisitDeclarations(expr->scope()->declarations()); - VisitClassLiteralContents(expr); - } + VisitDeclarations(expr->scope()->declarations()); + VisitClassLiteralContents(expr); } } @@ -1644,8 +1639,7 @@ void AstGraphBuilder::VisitClassLiteralContents(ClassLiteral* expr) { literal = NewNode(op, literal, proto); // Assign to class variable. - if (expr->scope() != NULL) { - DCHECK_NOT_NULL(expr->class_variable_proxy()); + if (expr->class_variable_proxy() != nullptr) { Variable* var = expr->class_variable_proxy()->var(); FrameStateBeforeAndAfter states(this, BailoutId::None()); VectorSlotPair feedback = CreateVectorSlotPair( diff --git a/src/full-codegen/full-codegen.cc b/src/full-codegen/full-codegen.cc index d7e95fbbec..8cb9dc39f0 100644 --- a/src/full-codegen/full-codegen.cc +++ b/src/full-codegen/full-codegen.cc @@ -1273,8 +1273,7 @@ void FullCodeGenerator::VisitClassLiteral(ClassLiteral* lit) { EmitClassDefineProperties(lit); - if (lit->scope() != NULL) { - DCHECK_NOT_NULL(lit->class_variable_proxy()); + if (lit->class_variable_proxy() != nullptr) { EmitVariableAssignment(lit->class_variable_proxy()->var(), Token::INIT_CONST, lit->ProxySlot()); } diff --git a/src/parser.cc b/src/parser.cc index 3d61c7e71b..e3a62c1ab2 100644 --- a/src/parser.cc +++ b/src/parser.cc @@ -4895,15 +4895,13 @@ ClassLiteral* Parser::ParseClassLiteral(const AstRawString* name, 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); if (name != NULL) { DCHECK_NOT_NULL(proxy); 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,