Commit e9887b6a authored by verwaest's avatar verwaest Committed by Commit bot

Allocate block scopes in block states when possible

This is another step towards lazily allocating them in the block state.
ClassLiteral should also have a lazy block-scope for the outermost scope,
but currently that doesn't work due to the parameter initializer rewriter
and minor implementation details in ignition and turbofan.

BUG=v8:5209

Review-Url: https://codereview.chromium.org/2166843003
Cr-Commit-Position: refs/heads/master@{#38196}
parent 205457b1
...@@ -283,6 +283,7 @@ class ParserBase : public Traits { ...@@ -283,6 +283,7 @@ class ParserBase : public Traits {
class ScopeState BASE_EMBEDDED { class ScopeState BASE_EMBEDDED {
public: public:
V8_INLINE Scope* scope() const { return scope_; } V8_INLINE Scope* scope() const { return scope_; }
Zone* zone() const { return scope_->zone(); }
protected: protected:
ScopeState(ScopeState** scope_stack, Scope* scope) ScopeState(ScopeState** scope_stack, Scope* scope)
...@@ -291,11 +292,9 @@ class ParserBase : public Traits { ...@@ -291,11 +292,9 @@ class ParserBase : public Traits {
} }
~ScopeState() { *scope_stack_ = outer_scope_; } ~ScopeState() { *scope_stack_ = outer_scope_; }
Zone* zone() const { return scope_->zone(); }
private: private:
ScopeState** scope_stack_; ScopeState** const scope_stack_;
ScopeState* outer_scope_; ScopeState* const outer_scope_;
Scope* scope_; Scope* scope_;
}; };
...@@ -303,6 +302,31 @@ class ParserBase : public Traits { ...@@ -303,6 +302,31 @@ class ParserBase : public Traits {
public: public:
BlockState(ScopeState** scope_stack, Scope* scope) BlockState(ScopeState** scope_stack, Scope* scope)
: ScopeState(scope_stack, scope) {} : ScopeState(scope_stack, scope) {}
// BlockState(ScopeState**) automatically manages Scope(BLOCK_SCOPE)
// allocation.
// TODO(verwaest): Move to LazyBlockState class that only allocates the
// scope when needed.
explicit BlockState(ScopeState** scope_stack)
: ScopeState(scope_stack, NewScope(*scope_stack)) {}
void SetNonlinear() { this->scope()->SetNonlinear(); }
void set_start_position(int pos) { this->scope()->set_start_position(pos); }
void set_end_position(int pos) { this->scope()->set_end_position(pos); }
void set_is_hidden() { this->scope()->set_is_hidden(); }
Scope* FinalizedBlockScope() const {
return this->scope()->FinalizeBlockScope();
}
LanguageMode language_mode() const {
return this->scope()->language_mode();
}
private:
Scope* NewScope(ScopeState* outer_state) {
Scope* parent = outer_state->scope();
Zone* zone = outer_state->zone();
return new (zone) Scope(zone, parent, BLOCK_SCOPE, kNormalFunction);
}
}; };
struct DestructuringAssignment { struct DestructuringAssignment {
......
...@@ -2299,13 +2299,12 @@ Block* Parser::ParseBlock(ZoneList<const AstRawString*>* labels, bool* ok) { ...@@ -2299,13 +2299,12 @@ Block* Parser::ParseBlock(ZoneList<const AstRawString*>* labels, bool* ok) {
// Construct block expecting 16 statements. // Construct block expecting 16 statements.
Block* body = factory()->NewBlock(labels, 16, false, kNoSourcePosition); Block* body = factory()->NewBlock(labels, 16, false, kNoSourcePosition);
Scope* block_scope = NewScope(BLOCK_SCOPE);
// Parse the statements and collect escaping labels. // Parse the statements and collect escaping labels.
Expect(Token::LBRACE, CHECK_OK); Expect(Token::LBRACE, CHECK_OK);
block_scope->set_start_position(scanner()->location().beg_pos);
{ {
BlockState block_state(&scope_state_, block_scope); BlockState block_state(&scope_state_);
block_state.set_start_position(scanner()->location().beg_pos);
Target target(&this->target_stack_, body); Target target(&this->target_stack_, body);
while (peek() != Token::RBRACE) { while (peek() != Token::RBRACE) {
...@@ -2314,11 +2313,11 @@ Block* Parser::ParseBlock(ZoneList<const AstRawString*>* labels, bool* ok) { ...@@ -2314,11 +2313,11 @@ Block* Parser::ParseBlock(ZoneList<const AstRawString*>* labels, bool* ok) {
body->statements()->Add(stat, zone()); body->statements()->Add(stat, zone());
} }
} }
}
Expect(Token::RBRACE, CHECK_OK); Expect(Token::RBRACE, CHECK_OK);
block_scope->set_end_position(scanner()->location().end_pos); block_state.set_end_position(scanner()->location().end_pos);
block_scope = block_scope->FinalizeBlockScope(); body->set_scope(block_state.FinalizedBlockScope());
body->set_scope(block_scope); }
return body; return body;
} }
...@@ -2915,15 +2914,14 @@ Statement* Parser::ParseSwitchStatement(ZoneList<const AstRawString*>* labels, ...@@ -2915,15 +2914,14 @@ Statement* Parser::ParseSwitchStatement(ZoneList<const AstRawString*>* labels,
zone()); zone());
Block* cases_block = factory()->NewBlock(NULL, 1, false, kNoSourcePosition); Block* cases_block = factory()->NewBlock(NULL, 1, false, kNoSourcePosition);
Scope* cases_scope = NewScope(BLOCK_SCOPE);
cases_scope->SetNonlinear();
SwitchStatement* switch_statement = SwitchStatement* switch_statement =
factory()->NewSwitchStatement(labels, switch_pos); factory()->NewSwitchStatement(labels, switch_pos);
cases_scope->set_start_position(scanner()->location().beg_pos);
{ {
BlockState cases_block_state(&scope_state_, cases_scope); BlockState cases_block_state(&scope_state_);
cases_block_state.set_start_position(scanner()->location().beg_pos);
cases_block_state.SetNonlinear();
Target target(&this->target_stack_, switch_statement); Target target(&this->target_stack_, switch_statement);
Expression* tag_read = factory()->NewVariableProxy(tag_variable); Expression* tag_read = factory()->NewVariableProxy(tag_variable);
...@@ -2938,12 +2936,11 @@ Statement* Parser::ParseSwitchStatement(ZoneList<const AstRawString*>* labels, ...@@ -2938,12 +2936,11 @@ Statement* Parser::ParseSwitchStatement(ZoneList<const AstRawString*>* labels,
} }
switch_statement->Initialize(tag_read, cases); switch_statement->Initialize(tag_read, cases);
cases_block->statements()->Add(switch_statement, zone()); cases_block->statements()->Add(switch_statement, zone());
}
Expect(Token::RBRACE, CHECK_OK); Expect(Token::RBRACE, CHECK_OK);
cases_scope->set_end_position(scanner()->location().end_pos); cases_block_state.set_end_position(scanner()->location().end_pos);
cases_scope = cases_scope->FinalizeBlockScope(); cases_block->set_scope(cases_block_state.FinalizedBlockScope());
cases_block->set_scope(cases_scope); }
switch_block->statements()->Add(cases_block, zone()); switch_block->statements()->Add(cases_block, zone());
...@@ -3028,10 +3025,9 @@ TryStatement* Parser::ParseTryStatement(bool* ok) { ...@@ -3028,10 +3025,9 @@ TryStatement* Parser::ParseTryStatement(bool* ok) {
// Create a block scope to hold any lexical declarations created // Create a block scope to hold any lexical declarations created
// as part of destructuring the catch parameter. // as part of destructuring the catch parameter.
Scope* block_scope = NewScope(BLOCK_SCOPE);
block_scope->set_start_position(scanner()->location().beg_pos);
{ {
BlockState block_state(&scope_state_, block_scope); BlockState block_state(&scope_state_);
block_state.set_start_position(scanner()->location().beg_pos);
Target target(&this->target_stack_, catch_block); Target target(&this->target_stack_, catch_block);
const AstRawString* name = ast_value_factory()->dot_catch_string(); const AstRawString* name = ast_value_factory()->dot_catch_string();
...@@ -3097,10 +3093,9 @@ TryStatement* Parser::ParseTryStatement(bool* ok) { ...@@ -3097,10 +3093,9 @@ TryStatement* Parser::ParseTryStatement(bool* ok) {
return nullptr; return nullptr;
} }
} }
block_state.set_end_position(scanner()->location().end_pos);
catch_block->set_scope(block_state.FinalizedBlockScope());
} }
block_scope->set_end_position(scanner()->location().end_pos);
block_scope = block_scope->FinalizeBlockScope();
catch_block->set_scope(block_scope);
} }
catch_scope->set_end_position(scanner()->location().end_pos); catch_scope->set_end_position(scanner()->location().end_pos);
...@@ -3664,15 +3659,13 @@ Statement* Parser::ParseScopedStatement(ZoneList<const AstRawString*>* labels, ...@@ -3664,15 +3659,13 @@ Statement* Parser::ParseScopedStatement(ZoneList<const AstRawString*>* labels,
} }
// Make a block around the statement for a lexical binding // Make a block around the statement for a lexical binding
// is introduced by a FunctionDeclaration. // is introduced by a FunctionDeclaration.
Scope* body_scope = NewScope(BLOCK_SCOPE); BlockState block_state(&scope_state_);
body_scope->set_start_position(scanner()->location().beg_pos); block_state.set_start_position(scanner()->location().beg_pos);
BlockState block_state(&scope_state_, body_scope);
Block* block = factory()->NewBlock(NULL, 1, false, kNoSourcePosition); Block* block = factory()->NewBlock(NULL, 1, false, kNoSourcePosition);
Statement* body = ParseFunctionDeclaration(CHECK_OK); Statement* body = ParseFunctionDeclaration(CHECK_OK);
block->statements()->Add(body, zone()); block->statements()->Add(body, zone());
body_scope->set_end_position(scanner()->location().end_pos); block_state.set_end_position(scanner()->location().end_pos);
body_scope = body_scope->FinalizeBlockScope(); block->set_scope(block_state.FinalizedBlockScope());
block->set_scope(body_scope);
return block; return block;
} }
} }
...@@ -3685,13 +3678,11 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels, ...@@ -3685,13 +3678,11 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
bool bound_names_are_lexical = false; bool bound_names_are_lexical = false;
// Create an in-between scope for let-bound iteration variables. // Create an in-between scope for let-bound iteration variables.
Scope* for_scope = NewScope(BLOCK_SCOPE); BlockState for_state(&scope_state_);
BlockState block_state(&scope_state_, for_scope);
Expect(Token::FOR, CHECK_OK); Expect(Token::FOR, CHECK_OK);
Expect(Token::LPAREN, CHECK_OK); Expect(Token::LPAREN, CHECK_OK);
for_scope->set_start_position(scanner()->location().beg_pos); for_state.set_start_position(scanner()->location().beg_pos);
for_scope->set_is_hidden(); for_state.set_is_hidden();
DeclarationParsingResult parsing_result; DeclarationParsingResult parsing_result;
if (peek() != Token::SEMICOLON) { if (peek() != Token::SEMICOLON) {
if (peek() == Token::VAR || peek() == Token::CONST || if (peek() == Token::VAR || peek() == Token::CONST ||
...@@ -3790,8 +3781,6 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels, ...@@ -3790,8 +3781,6 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
Expect(Token::RPAREN, CHECK_OK); Expect(Token::RPAREN, CHECK_OK);
Scope* body_scope = NewScope(BLOCK_SCOPE);
body_scope->set_start_position(scanner()->location().beg_pos);
Block* body_block = Block* body_block =
factory()->NewBlock(NULL, 3, false, kNoSourcePosition); factory()->NewBlock(NULL, 3, false, kNoSourcePosition);
...@@ -3800,7 +3789,8 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels, ...@@ -3800,7 +3789,8 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
{ {
ReturnExprScope no_tail_calls(function_state_, ReturnExprScope no_tail_calls(function_state_,
ReturnExprContext::kInsideForInOfBody); ReturnExprContext::kInsideForInOfBody);
BlockState block_state(&scope_state_, body_scope); BlockState block_state(&scope_state_);
block_state.set_start_position(scanner()->location().beg_pos);
Statement* body = ParseScopedStatement(NULL, true, CHECK_OK); Statement* body = ParseScopedStatement(NULL, true, CHECK_OK);
...@@ -3858,10 +3848,9 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels, ...@@ -3858,10 +3848,9 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
factory()->NewVariableProxy(temp, each_beg_pos, each_end_pos); factory()->NewVariableProxy(temp, each_beg_pos, each_end_pos);
final_loop = InitializeForEachStatement( final_loop = InitializeForEachStatement(
loop, temp_proxy, enumerable, body_block, each_keyword_position); loop, temp_proxy, enumerable, body_block, each_keyword_position);
block_state.set_end_position(scanner()->location().end_pos);
body_block->set_scope(block_state.FinalizedBlockScope());
} }
body_scope->set_end_position(scanner()->location().end_pos);
body_scope = body_scope->FinalizeBlockScope();
body_block->set_scope(body_scope);
// Create a TDZ for any lexically-bound names. // Create a TDZ for any lexically-bound names.
if (bound_names_are_lexical) { if (bound_names_are_lexical) {
...@@ -3883,8 +3872,8 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels, ...@@ -3883,8 +3872,8 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
} }
} }
for_scope->set_end_position(scanner()->location().end_pos); for_state.set_end_position(scanner()->location().end_pos);
for_scope = for_scope->FinalizeBlockScope(); Scope* for_scope = for_state.FinalizedBlockScope();
// Parsed for-in loop w/ variable declarations. // Parsed for-in loop w/ variable declarations.
if (init_block != nullptr) { if (init_block != nullptr) {
init_block->statements()->Add(final_loop, zone()); init_block->statements()->Add(final_loop, zone());
...@@ -3947,9 +3936,7 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels, ...@@ -3947,9 +3936,7 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
Statement* final_loop = InitializeForEachStatement( Statement* final_loop = InitializeForEachStatement(
loop, expression, enumerable, body, each_keyword_position); loop, expression, enumerable, body, each_keyword_position);
for_scope->set_end_position(scanner()->location().end_pos); DCHECK_NULL(for_state.FinalizedBlockScope());
for_scope = for_scope->FinalizeBlockScope();
DCHECK(for_scope == nullptr);
return final_loop; return final_loop;
} else { } else {
...@@ -3972,8 +3959,9 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels, ...@@ -3972,8 +3959,9 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
// If there are let bindings, then condition and the next statement of the // If there are let bindings, then condition and the next statement of the
// for loop must be parsed in a new scope. // for loop must be parsed in a new scope.
Scope* inner_scope = scope(); Scope* inner_scope = scope();
// TODO(verwaest): Allocate this through a ScopeState as well.
if (bound_names_are_lexical && bound_names.length() > 0) { if (bound_names_are_lexical && bound_names.length() > 0) {
inner_scope = NewScopeWithParent(for_scope, BLOCK_SCOPE); inner_scope = NewScopeWithParent(inner_scope, BLOCK_SCOPE);
inner_scope->set_start_position(scanner()->location().beg_pos); inner_scope->set_start_position(scanner()->location().beg_pos);
} }
{ {
...@@ -3995,14 +3983,13 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels, ...@@ -3995,14 +3983,13 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
Statement* result = NULL; Statement* result = NULL;
if (bound_names_are_lexical && bound_names.length() > 0) { if (bound_names_are_lexical && bound_names.length() > 0) {
BlockState block_state(&scope_state_, for_scope);
result = DesugarLexicalBindingsInForStatement( result = DesugarLexicalBindingsInForStatement(
inner_scope, parsing_result.descriptor.mode, &bound_names, loop, init, inner_scope, parsing_result.descriptor.mode, &bound_names, loop, init,
cond, next, body, CHECK_OK); cond, next, body, CHECK_OK);
for_scope->set_end_position(scanner()->location().end_pos); for_state.set_end_position(scanner()->location().end_pos);
} else { } else {
for_scope->set_end_position(scanner()->location().end_pos); for_state.set_end_position(scanner()->location().end_pos);
for_scope = for_scope->FinalizeBlockScope(); Scope* for_scope = for_state.FinalizedBlockScope();
if (for_scope) { if (for_scope) {
// Rewrite a for statement of the form // Rewrite a for statement of the form
// for (const x = i; c; n) b // for (const x = i; c; n) b
...@@ -5014,30 +5001,30 @@ Expression* Parser::ParseClassLiteral(ExpressionClassifier* classifier, ...@@ -5014,30 +5001,30 @@ Expression* Parser::ParseClassLiteral(ExpressionClassifier* classifier,
ReportMessageAt(class_name_location, ReportMessageAt(class_name_location,
MessageTemplate::kUnexpectedStrictReserved); MessageTemplate::kUnexpectedStrictReserved);
*ok = false; *ok = false;
return NULL; return nullptr;
} }
if (IsEvalOrArguments(name)) { if (IsEvalOrArguments(name)) {
ReportMessageAt(class_name_location, MessageTemplate::kStrictEvalArguments); ReportMessageAt(class_name_location, MessageTemplate::kStrictEvalArguments);
*ok = false; *ok = false;
return NULL; return nullptr;
} }
Scope* block_scope = NewScope(BLOCK_SCOPE); BlockState block_state(&scope_state_);
BlockState block_state(&scope_state_, block_scope);
RaiseLanguageMode(STRICT); RaiseLanguageMode(STRICT);
scope()->SetScopeName(name); scope()->SetScopeName(name);
VariableProxy* proxy = NULL; VariableProxy* proxy = nullptr;
if (name != NULL) { if (name != nullptr) {
proxy = NewUnresolved(name, CONST); proxy = NewUnresolved(name, CONST);
Declaration* declaration = // TODO(verwaest): declare via block_state.
factory()->NewVariableDeclaration(proxy, CONST, block_scope, pos); Declaration* declaration = factory()->NewVariableDeclaration(
proxy, CONST, block_state.scope(), pos);
Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK); Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK);
} }
Expression* extends = NULL; Expression* extends = nullptr;
if (Check(Token::EXTENDS)) { if (Check(Token::EXTENDS)) {
block_scope->set_start_position(scanner()->location().end_pos); block_state.set_start_position(scanner()->location().end_pos);
ExpressionClassifier extends_classifier(this); ExpressionClassifier extends_classifier(this);
extends = ParseLeftHandSideExpression(&extends_classifier, CHECK_OK); extends = ParseLeftHandSideExpression(&extends_classifier, CHECK_OK);
CheckNoTailCallExpressions(&extends_classifier, CHECK_OK); CheckNoTailCallExpressions(&extends_classifier, CHECK_OK);
...@@ -5047,13 +5034,13 @@ Expression* Parser::ParseClassLiteral(ExpressionClassifier* classifier, ...@@ -5047,13 +5034,13 @@ Expression* Parser::ParseClassLiteral(ExpressionClassifier* classifier,
ExpressionClassifier::ExpressionProductions); ExpressionClassifier::ExpressionProductions);
} }
} else { } else {
block_scope->set_start_position(scanner()->location().end_pos); block_state.set_start_position(scanner()->location().end_pos);
} }
ClassLiteralChecker checker(this); ClassLiteralChecker checker(this);
ZoneList<ObjectLiteral::Property*>* properties = NewPropertyList(4, zone()); ZoneList<ObjectLiteral::Property*>* properties = NewPropertyList(4, zone());
FunctionLiteral* constructor = NULL; FunctionLiteral* constructor = nullptr;
bool has_seen_constructor = false; bool has_seen_constructor = false;
Expect(Token::LBRACE, CHECK_OK); Expect(Token::LBRACE, CHECK_OK);
...@@ -5076,7 +5063,7 @@ Expression* Parser::ParseClassLiteral(ExpressionClassifier* classifier, ...@@ -5076,7 +5063,7 @@ Expression* Parser::ParseClassLiteral(ExpressionClassifier* classifier,
ExpressionClassifier::ExpressionProductions); ExpressionClassifier::ExpressionProductions);
} }
if (has_seen_constructor && constructor == NULL) { if (has_seen_constructor && constructor == nullptr) {
constructor = GetPropertyValue(property)->AsFunctionLiteral(); constructor = GetPropertyValue(property)->AsFunctionLiteral();
DCHECK_NOT_NULL(constructor); DCHECK_NOT_NULL(constructor);
constructor->set_raw_name( constructor->set_raw_name(
...@@ -5085,7 +5072,7 @@ Expression* Parser::ParseClassLiteral(ExpressionClassifier* classifier, ...@@ -5085,7 +5072,7 @@ Expression* Parser::ParseClassLiteral(ExpressionClassifier* classifier,
properties->Add(property, zone()); properties->Add(property, zone());
} }
if (fni_ != NULL) fni_->Infer(); if (fni_ != nullptr) fni_->Infer();
if (property_name != ast_value_factory()->constructor_string()) { if (property_name != ast_value_factory()->constructor_string()) {
SetFunctionNameFromPropertyName(property, property_name); SetFunctionNameFromPropertyName(property, property_name);
...@@ -5095,25 +5082,24 @@ Expression* Parser::ParseClassLiteral(ExpressionClassifier* classifier, ...@@ -5095,25 +5082,24 @@ Expression* Parser::ParseClassLiteral(ExpressionClassifier* classifier,
Expect(Token::RBRACE, CHECK_OK); Expect(Token::RBRACE, CHECK_OK);
int end_pos = scanner()->location().end_pos; int end_pos = scanner()->location().end_pos;
if (constructor == NULL) { if (constructor == nullptr) {
DCHECK_EQ(scope(), block_scope);
constructor = DefaultConstructor(name, has_extends, pos, end_pos, constructor = DefaultConstructor(name, has_extends, pos, end_pos,
block_scope->language_mode()); block_state.language_mode());
} }
// Note that we do not finalize this block scope because it is // Note that we do not finalize this block scope because it is
// used as a sentinel value indicating an anonymous class. // used as a sentinel value indicating an anonymous class.
block_scope->set_end_position(end_pos); block_state.set_end_position(end_pos);
if (name != NULL) { if (name != nullptr) {
DCHECK_NOT_NULL(proxy); DCHECK_NOT_NULL(proxy);
proxy->var()->set_initializer_position(end_pos); proxy->var()->set_initializer_position(end_pos);
} }
Block* do_block = factory()->NewBlock(nullptr, 1, false, pos); Block* do_block = factory()->NewBlock(nullptr, 1, false, pos);
do_block->set_scope(block_scope);
Variable* result_var = Variable* result_var =
block_scope->NewTemporary(ast_value_factory()->empty_string()); scope()->NewTemporary(ast_value_factory()->empty_string());
do_block->set_scope(block_state.FinalizedBlockScope());
DoExpression* do_expr = factory()->NewDoExpression(do_block, result_var, pos); DoExpression* do_expr = factory()->NewDoExpression(do_block, result_var, pos);
ClassLiteral* class_literal = factory()->NewClassLiteral( ClassLiteral* class_literal = factory()->NewClassLiteral(
......
...@@ -305,8 +305,7 @@ PreParser::Statement PreParser::ParseScopedStatement(bool legacy, bool* ok) { ...@@ -305,8 +305,7 @@ PreParser::Statement PreParser::ParseScopedStatement(bool legacy, bool* ok) {
(legacy && allow_harmony_restrictive_declarations())) { (legacy && allow_harmony_restrictive_declarations())) {
return ParseSubStatement(kDisallowLabelledFunctionStatement, ok); return ParseSubStatement(kDisallowLabelledFunctionStatement, ok);
} else { } else {
Scope* body_scope = NewScope(BLOCK_SCOPE); BlockState block_state(&scope_state_);
BlockState block_state(&scope_state_, body_scope);
return ParseFunctionDeclaration(ok); return ParseFunctionDeclaration(ok);
} }
} }
...@@ -476,11 +475,10 @@ PreParser::Statement PreParser::ParseBlock(bool* ok) { ...@@ -476,11 +475,10 @@ PreParser::Statement PreParser::ParseBlock(bool* ok) {
// Block :: // Block ::
// '{' StatementList '}' // '{' StatementList '}'
Scope* block_scope = NewScope(BLOCK_SCOPE);
Expect(Token::LBRACE, CHECK_OK); Expect(Token::LBRACE, CHECK_OK);
Statement final = Statement::Default(); Statement final = Statement::Default();
{ {
BlockState block_state(&scope_state_, block_scope); BlockState block_state(&scope_state_);
while (peek() != Token::RBRACE) { while (peek() != Token::RBRACE) {
final = ParseStatementListItem(CHECK_OK); final = ParseStatementListItem(CHECK_OK);
} }
...@@ -805,9 +803,8 @@ PreParser::Statement PreParser::ParseSwitchStatement(bool* ok) { ...@@ -805,9 +803,8 @@ PreParser::Statement PreParser::ParseSwitchStatement(bool* ok) {
ParseExpression(true, CHECK_OK); ParseExpression(true, CHECK_OK);
Expect(Token::RPAREN, CHECK_OK); Expect(Token::RPAREN, CHECK_OK);
Scope* cases_scope = NewScope(BLOCK_SCOPE);
{ {
BlockState cases_block_state(&scope_state_, cases_scope); BlockState cases_block_state(&scope_state_);
Expect(Token::LBRACE, CHECK_OK); Expect(Token::LBRACE, CHECK_OK);
Token::Value token = peek(); Token::Value token = peek();
while (token != Token::RBRACE) { while (token != Token::RBRACE) {
...@@ -866,10 +863,9 @@ PreParser::Statement PreParser::ParseForStatement(bool* ok) { ...@@ -866,10 +863,9 @@ PreParser::Statement PreParser::ParseForStatement(bool* ok) {
// 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
// Create an in-between scope for let-bound iteration variables. // Create an in-between scope for let-bound iteration variables.
Scope* for_scope = NewScope(BLOCK_SCOPE);
bool has_lexical = false; bool has_lexical = false;
BlockState block_state(&scope_state_, for_scope); BlockState block_state(&scope_state_);
Expect(Token::FOR, CHECK_OK); Expect(Token::FOR, CHECK_OK);
Expect(Token::LPAREN, CHECK_OK); Expect(Token::LPAREN, CHECK_OK);
if (peek() != Token::SEMICOLON) { if (peek() != Token::SEMICOLON) {
...@@ -956,9 +952,8 @@ PreParser::Statement PreParser::ParseForStatement(bool* ok) { ...@@ -956,9 +952,8 @@ PreParser::Statement PreParser::ParseForStatement(bool* ok) {
} }
Expect(Token::RPAREN, CHECK_OK); Expect(Token::RPAREN, CHECK_OK);
Scope* body_scope = NewScope(BLOCK_SCOPE);
{ {
BlockState block_state(&scope_state_, body_scope); BlockState block_state(&scope_state_);
ParseScopedStatement(true, CHECK_OK); ParseScopedStatement(true, CHECK_OK);
} }
return Statement::Default(); return Statement::Default();
...@@ -972,7 +967,8 @@ PreParser::Statement PreParser::ParseForStatement(bool* ok) { ...@@ -972,7 +967,8 @@ PreParser::Statement PreParser::ParseForStatement(bool* ok) {
// If there are let bindings, then condition and the next statement of the // If there are let bindings, then condition and the next statement of the
// for loop must be parsed in a new scope. // for loop must be parsed in a new scope.
Scope* inner_scope = scope(); Scope* inner_scope = scope();
if (has_lexical) inner_scope = NewScopeWithParent(for_scope, BLOCK_SCOPE); // TODO(verwaest): Allocate this through a ScopeState as well.
if (has_lexical) inner_scope = NewScopeWithParent(inner_scope, BLOCK_SCOPE);
{ {
BlockState block_state(&scope_state_, inner_scope); BlockState block_state(&scope_state_, inner_scope);
...@@ -1050,9 +1046,8 @@ PreParser::Statement PreParser::ParseTryStatement(bool* ok) { ...@@ -1050,9 +1046,8 @@ PreParser::Statement PreParser::ParseTryStatement(bool* ok) {
collect_tail_call_expressions_scope( collect_tail_call_expressions_scope(
function_state_, &tail_call_expressions_in_catch_block); function_state_, &tail_call_expressions_in_catch_block);
BlockState block_state(&scope_state_, catch_scope); BlockState block_state(&scope_state_, catch_scope);
Scope* block_scope = NewScope(BLOCK_SCOPE);
{ {
BlockState block_state(&scope_state_, block_scope); BlockState block_state(&scope_state_);
ParseBlock(CHECK_OK); ParseBlock(CHECK_OK);
} }
} }
...@@ -1227,9 +1222,8 @@ PreParserExpression PreParser::ParseClassLiteral( ...@@ -1227,9 +1222,8 @@ PreParserExpression PreParser::ParseClassLiteral(
} }
LanguageMode class_language_mode = language_mode(); LanguageMode class_language_mode = language_mode();
Scope* scope = NewScope(BLOCK_SCOPE); BlockState block_state(&scope_state_);
BlockState block_state(&scope_state_, scope); scope()->SetLanguageMode(
this->scope()->SetLanguageMode(
static_cast<LanguageMode>(class_language_mode | STRICT)); static_cast<LanguageMode>(class_language_mode | STRICT));
// TODO(marja): Make PreParser use scope names too. // TODO(marja): Make PreParser use scope names too.
// this->scope()->SetScopeName(name); // this->scope()->SetScopeName(name);
......
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