Commit 4f552f5a authored by verwaest's avatar verwaest Committed by Commit bot

Introduce parent ScopeState class and track the scope through the state in the parser

This will allow us to move more state from Scope into ScopeState and lazily allocate full Scopes only when needed.

BUG=v8:5209

Review-Url: https://codereview.chromium.org/2160593002
Cr-Commit-Position: refs/heads/master@{#37858}
parent 7c3ddd2c
This diff is collapsed.
This diff is collapsed.
......@@ -130,16 +130,17 @@ PreParser::PreParseResult PreParser::PreParseLazyFunction(
log_ = log;
use_counts_ = use_counts;
// Lazy functions always have trivial outer scopes (no with/catch scopes).
Scope* top_scope = NewScope(scope_, SCRIPT_SCOPE);
PreParserFactory top_factory(NULL);
FunctionState top_state(&function_state_, &scope_, top_scope, kNormalFunction,
&top_factory);
scope_->SetLanguageMode(language_mode);
Scope* function_scope = NewScope(scope_, FUNCTION_SCOPE, kind);
DCHECK_NULL(scope_state_);
Scope* top_scope = NewScope(nullptr, SCRIPT_SCOPE);
PreParserFactory top_factory(nullptr);
FunctionState top_state(&function_state_, &scope_state_, top_scope,
kNormalFunction, &top_factory);
scope()->SetLanguageMode(language_mode);
Scope* function_scope = NewScope(scope(), FUNCTION_SCOPE, kind);
if (!has_simple_parameters) function_scope->SetHasNonSimpleParameters();
PreParserFactory function_factory(NULL);
FunctionState function_state(&function_state_, &scope_, function_scope, kind,
&function_factory);
PreParserFactory function_factory(nullptr);
FunctionState function_state(&function_state_, &scope_state_, function_scope,
kind, &function_factory);
DCHECK_EQ(Token::LBRACE, scanner()->current_token());
bool ok = true;
int start_position = peek_position();
......@@ -153,7 +154,7 @@ PreParser::PreParseResult PreParser::PreParseLazyFunction(
ReportUnexpectedToken(scanner()->current_token());
} else {
DCHECK_EQ(Token::RBRACE, scanner()->peek());
if (is_strict(scope_->language_mode())) {
if (is_strict(scope()->language_mode())) {
int end_pos = scanner()->location().end_pos;
CheckStrictOctalLiteral(start_position, end_pos, &ok);
CheckDecimalLiteralWithLeadingZero(use_counts, start_position, end_pos);
......@@ -253,13 +254,13 @@ void PreParser::ParseStatementList(int end_token, bool* ok,
bool use_strict_found = statement.IsUseStrictLiteral();
if (use_strict_found) {
scope_->SetLanguageMode(
static_cast<LanguageMode>(scope_->language_mode() | STRICT));
scope()->SetLanguageMode(
static_cast<LanguageMode>(scope()->language_mode() | STRICT));
} else if (!statement.IsStringLiteral()) {
directive_prologue = false;
}
if (use_strict_found && !scope_->HasSimpleParameters()) {
if (use_strict_found && !scope()->HasSimpleParameters()) {
// TC39 deemed "use strict" directives to be an error when occurring
// in the body of a function with non-simple parameter list, on
// 29/7/2015. https://goo.gl/ueA7Ln
......@@ -306,8 +307,8 @@ PreParser::Statement PreParser::ParseScopedStatement(bool legacy, bool* ok) {
(legacy && allow_harmony_restrictive_declarations())) {
return ParseSubStatement(kDisallowLabelledFunctionStatement, ok);
} else {
Scope* body_scope = NewScope(scope_, BLOCK_SCOPE);
BlockState block_state(&scope_, body_scope);
Scope* body_scope = NewScope(scope(), BLOCK_SCOPE);
BlockState block_state(&scope_state_, body_scope);
return ParseFunctionDeclaration(ok);
}
}
......@@ -477,11 +478,11 @@ PreParser::Statement PreParser::ParseBlock(bool* ok) {
// Block ::
// '{' StatementList '}'
Scope* block_scope = NewScope(scope_, BLOCK_SCOPE);
Scope* block_scope = NewScope(scope(), BLOCK_SCOPE);
Expect(Token::LBRACE, CHECK_OK);
Statement final = Statement::Default();
{
BlockState block_state(&scope_, block_scope);
BlockState block_state(&scope_state_, block_scope);
while (peek() != Token::RBRACE) {
final = ParseStatementListItem(CHECK_OK);
}
......@@ -791,8 +792,8 @@ PreParser::Statement PreParser::ParseWithStatement(bool* ok) {
ParseExpression(true, CHECK_OK);
Expect(Token::RPAREN, CHECK_OK);
Scope* with_scope = NewScope(scope_, WITH_SCOPE);
BlockState block_state(&scope_, with_scope);
Scope* with_scope = NewScope(scope(), WITH_SCOPE);
BlockState block_state(&scope_state_, with_scope);
ParseScopedStatement(true, CHECK_OK);
return Statement::Default();
}
......@@ -807,9 +808,9 @@ PreParser::Statement PreParser::ParseSwitchStatement(bool* ok) {
ParseExpression(true, CHECK_OK);
Expect(Token::RPAREN, CHECK_OK);
Scope* cases_scope = NewScope(scope_, BLOCK_SCOPE);
Scope* cases_scope = NewScope(scope(), BLOCK_SCOPE);
{
BlockState cases_block_state(&scope_, cases_scope);
BlockState cases_block_state(&scope_state_, cases_scope);
Expect(Token::LBRACE, CHECK_OK);
Token::Value token = peek();
while (token != Token::RBRACE) {
......@@ -868,10 +869,10 @@ PreParser::Statement PreParser::ParseForStatement(bool* ok) {
// 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
// Create an in-between scope for let-bound iteration variables.
Scope* for_scope = NewScope(scope_, BLOCK_SCOPE);
Scope* for_scope = NewScope(scope(), BLOCK_SCOPE);
bool has_lexical = false;
BlockState block_state(&scope_, for_scope);
BlockState block_state(&scope_state_, for_scope);
Expect(Token::FOR, CHECK_OK);
Expect(Token::LPAREN, CHECK_OK);
if (peek() != Token::SEMICOLON) {
......@@ -958,9 +959,9 @@ PreParser::Statement PreParser::ParseForStatement(bool* ok) {
}
Expect(Token::RPAREN, CHECK_OK);
Scope* body_scope = NewScope(scope_, BLOCK_SCOPE);
Scope* body_scope = NewScope(scope(), BLOCK_SCOPE);
{
BlockState block_state(&scope_, body_scope);
BlockState block_state(&scope_state_, body_scope);
ParseScopedStatement(true, CHECK_OK);
}
return Statement::Default();
......@@ -973,11 +974,11 @@ PreParser::Statement PreParser::ParseForStatement(bool* ok) {
// If there are let bindings, then condition and the next statement of the
// for loop must be parsed in a new scope.
Scope* inner_scope = scope_;
Scope* inner_scope = scope();
if (has_lexical) inner_scope = NewScope(for_scope, BLOCK_SCOPE);
{
BlockState block_state(&scope_, inner_scope);
BlockState block_state(&scope_state_, inner_scope);
if (peek() != Token::SEMICOLON) {
ParseExpression(true, CHECK_OK);
......@@ -1042,7 +1043,7 @@ PreParser::Statement PreParser::ParseTryStatement(bool* ok) {
if (tok == Token::CATCH) {
Consume(Token::CATCH);
Expect(Token::LPAREN, CHECK_OK);
Scope* catch_scope = NewScope(scope_, CATCH_SCOPE);
Scope* catch_scope = NewScope(scope(), CATCH_SCOPE);
ExpressionClassifier pattern_classifier(this);
ParsePrimaryExpression(&pattern_classifier, CHECK_OK);
ValidateBindingPattern(&pattern_classifier, CHECK_OK);
......@@ -1051,10 +1052,10 @@ PreParser::Statement PreParser::ParseTryStatement(bool* ok) {
CollectExpressionsInTailPositionToListScope
collect_tail_call_expressions_scope(
function_state_, &tail_call_expressions_in_catch_block);
BlockState block_state(&scope_, catch_scope);
Scope* block_scope = NewScope(scope_, BLOCK_SCOPE);
BlockState block_state(&scope_state_, catch_scope);
Scope* block_scope = NewScope(scope(), BLOCK_SCOPE);
{
BlockState block_state(&scope_, block_scope);
BlockState block_state(&scope_state_, block_scope);
ParseBlock(CHECK_OK);
}
}
......@@ -1109,12 +1110,12 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
// '(' FormalParameterList? ')' '{' FunctionBody '}'
// Parse function body.
bool outer_is_script_scope = scope_->is_script_scope();
Scope* function_scope = NewScope(scope_, FUNCTION_SCOPE, kind);
bool outer_is_script_scope = scope()->is_script_scope();
Scope* function_scope = NewScope(scope(), FUNCTION_SCOPE, kind);
function_scope->SetLanguageMode(language_mode);
PreParserFactory factory(NULL);
FunctionState function_state(&function_state_, &scope_, function_scope, kind,
&factory);
FunctionState function_state(&function_state_, &scope_state_, function_scope,
kind, &factory);
DuplicateFinder duplicate_finder(scanner()->unicode_cache());
ExpressionClassifier formals_classifier(this, &duplicate_finder);
......@@ -1209,7 +1210,7 @@ void PreParser::ParseLazyFunctionLiteralBody(bool* ok,
log_->LogFunction(body_start, body_end,
function_state_->materialized_literal_count(),
function_state_->expected_property_count(), language_mode(),
scope_->uses_super_property(), scope_->calls_eval());
scope()->uses_super_property(), scope()->calls_eval());
}
PreParserExpression PreParser::ParseClassLiteral(
......@@ -1230,12 +1231,12 @@ PreParserExpression PreParser::ParseClassLiteral(
}
LanguageMode class_language_mode = language_mode();
Scope* scope = NewScope(scope_, BLOCK_SCOPE);
BlockState block_state(&scope_, scope);
scope_->SetLanguageMode(
Scope* scope = NewScope(this->scope(), BLOCK_SCOPE);
BlockState block_state(&scope_state_, scope);
this->scope()->SetLanguageMode(
static_cast<LanguageMode>(class_language_mode | STRICT));
// TODO(marja): Make PreParser use scope names too.
// scope_->SetScopeName(name);
// this->scope()->SetScopeName(name);
bool has_extends = Check(Token::EXTENDS);
if (has_extends) {
......@@ -1312,7 +1313,7 @@ PreParserExpression PreParser::ParseDoExpression(bool* ok) {
void PreParserTraits::ParseAsyncArrowSingleExpressionBody(
PreParserStatementList body, bool accept_IN,
Type::ExpressionClassifier* classifier, int pos, bool* ok) {
Scope* scope = pre_parser_->scope_;
Scope* scope = pre_parser_->scope();
scope->ForceContextAllocation();
PreParserExpression return_value = pre_parser_->ParseAssignmentExpression(
......
......@@ -1037,7 +1037,8 @@ class PreParser : public ParserBase<PreParserTraits> {
// during parsing.
PreParseResult PreParseProgram(int* materialized_literals = 0,
bool is_module = false) {
Scope* scope = NewScope(scope_, SCRIPT_SCOPE);
DCHECK_NULL(scope_state_);
Scope* scope = NewScope(nullptr, SCRIPT_SCOPE);
// ModuleDeclarationInstantiation for Source Text Module Records creates a
// new Module Environment Record whose outer lexical environment record is
......@@ -1046,9 +1047,9 @@ class PreParser : public ParserBase<PreParserTraits> {
scope = NewScope(scope, MODULE_SCOPE);
}
PreParserFactory factory(NULL);
FunctionState top_scope(&function_state_, &scope_, scope, kNormalFunction,
&factory);
PreParserFactory factory(nullptr);
FunctionState top_scope(&function_state_, &scope_state_, scope,
kNormalFunction, &factory);
bool ok = true;
int start_position = scanner()->peek_location().beg_pos;
parsing_module_ = is_module;
......@@ -1056,7 +1057,7 @@ class PreParser : public ParserBase<PreParserTraits> {
if (stack_overflow()) return kPreParseStackOverflow;
if (!ok) {
ReportUnexpectedToken(scanner()->current_token());
} else if (is_strict(scope_->language_mode())) {
} else if (is_strict(this->scope()->language_mode())) {
CheckStrictOctalLiteral(start_position, scanner()->location().end_pos,
&ok);
CheckDecimalLiteralWithLeadingZero(use_counts_, start_position,
......@@ -1245,11 +1246,11 @@ PreParserStatementList PreParser::ParseEagerFunctionBody(
FunctionLiteral::FunctionType function_type, bool* ok) {
ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
Scope* inner_scope = scope_;
if (!parameters.is_simple) inner_scope = NewScope(scope_, BLOCK_SCOPE);
Scope* inner_scope = scope();
if (!parameters.is_simple) inner_scope = NewScope(scope(), BLOCK_SCOPE);
{
BlockState block_state(&scope_, inner_scope);
BlockState block_state(&scope_state_, inner_scope);
ParseStatementList(Token::RBRACE, ok);
if (!*ok) return PreParserStatementList();
}
......
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