Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(75)

Unified Diff: src/parsing/parser.cc

Issue 2307073002: [parser] Refactor of Parse*Statement*, part 1 (Closed)
Patch Set: Fix weird compilation bug with line continuation in comment Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/parsing/parser.cc
diff --git a/src/parsing/parser.cc b/src/parsing/parser.cc
index 9f18790eefce3cc4ff1a4637f29cd039e5b84262..78791ec905d48196e233de3be60258d67fdf262c 100644
--- a/src/parsing/parser.cc
+++ b/src/parsing/parser.cc
@@ -231,41 +231,39 @@ FunctionLiteral* Parser::DefaultConstructor(const AstRawString* name,
// 'continue' statement targets). Upon construction, a new target is
// added; it is removed upon destruction.
-class Target BASE_EMBEDDED {
+class ParserTarget BASE_EMBEDDED {
public:
- Target(Target** variable, BreakableStatement* statement)
- : variable_(variable), statement_(statement), previous_(*variable) {
- *variable = this;
+ ParserTarget(ParserBase<Parser>* parser, BreakableStatement* statement)
+ : variable_(&parser->impl()->target_stack_),
+ statement_(statement),
+ previous_(parser->impl()->target_stack_) {
+ parser->impl()->target_stack_ = this;
}
- ~Target() {
- *variable_ = previous_;
- }
+ ~ParserTarget() { *variable_ = previous_; }
- Target* previous() { return previous_; }
+ ParserTarget* previous() { return previous_; }
BreakableStatement* statement() { return statement_; }
private:
- Target** variable_;
+ ParserTarget** variable_;
BreakableStatement* statement_;
- Target* previous_;
+ ParserTarget* previous_;
};
-
-class TargetScope BASE_EMBEDDED {
+class ParserTargetScope BASE_EMBEDDED {
public:
- explicit TargetScope(Target** variable)
- : variable_(variable), previous_(*variable) {
- *variable = NULL;
+ explicit ParserTargetScope(ParserBase<Parser>* parser)
+ : variable_(&parser->impl()->target_stack_),
+ previous_(parser->impl()->target_stack_) {
+ parser->impl()->target_stack_ = nullptr;
}
- ~TargetScope() {
- *variable_ = previous_;
- }
+ ~ParserTargetScope() { *variable_ = previous_; }
private:
- Target** variable_;
- Target* previous_;
+ ParserTarget** variable_;
+ ParserTarget* previous_;
};
@@ -931,131 +929,6 @@ FunctionLiteral* Parser::DoParseLazy(ParseInfo* info,
return result;
}
-
-void Parser::ParseStatementList(ZoneList<Statement*>* body, int end_token,
- bool* ok) {
- // StatementList ::
- // (StatementListItem)* <end_token>
-
- // Allocate a target stack to use for this set of source
- // elements. This way, all scripts and functions get their own
- // target stack thus avoiding illegal breaks and continues across
- // functions.
- TargetScope scope(&this->target_stack_);
-
- DCHECK(body != NULL);
- bool directive_prologue = true; // Parsing directive prologue.
-
- while (peek() != end_token) {
- if (directive_prologue && peek() != Token::STRING) {
- directive_prologue = false;
- }
-
- Scanner::Location token_loc = scanner()->peek_location();
- Statement* stat = ParseStatementListItem(CHECK_OK_VOID);
- if (stat == NULL || stat->IsEmpty()) {
- directive_prologue = false; // End of directive prologue.
- continue;
- }
-
- if (directive_prologue) {
- // A shot at a directive.
- ExpressionStatement* e_stat;
- Literal* literal;
- // Still processing directive prologue?
- if ((e_stat = stat->AsExpressionStatement()) != NULL &&
- (literal = e_stat->expression()->AsLiteral()) != NULL &&
- literal->raw_value()->IsString()) {
- // Check "use strict" directive (ES5 14.1), "use asm" directive.
- bool use_strict_found =
- literal->raw_value()->AsString() ==
- ast_value_factory()->use_strict_string() &&
- token_loc.end_pos - token_loc.beg_pos ==
- ast_value_factory()->use_strict_string()->length() + 2;
- if (use_strict_found) {
- if (is_sloppy(language_mode())) {
- RaiseLanguageMode(STRICT);
- }
-
- if (!this->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
- const AstRawString* string = literal->raw_value()->AsString();
- ReportMessageAt(token_loc,
- MessageTemplate::kIllegalLanguageModeDirective,
- string);
- *ok = false;
- return;
- }
- // Because declarations in strict eval code don't leak into the scope
- // of the eval call, it is likely that functions declared in strict
- // eval code will be used within the eval code, so lazy parsing is
- // probably not a win.
- if (this->scope()->is_eval_scope()) mode_ = PARSE_EAGERLY;
- } else if (literal->raw_value()->AsString() ==
- ast_value_factory()->use_asm_string() &&
- token_loc.end_pos - token_loc.beg_pos ==
- ast_value_factory()->use_asm_string()->length() + 2) {
- // Store the usage count; The actual use counter on the isolate is
- // incremented after parsing is done.
- ++use_counts_[v8::Isolate::kUseAsm];
- DCHECK(this->scope()->is_declaration_scope());
- this->scope()->AsDeclarationScope()->set_asm_module();
- } else {
- // Should not change mode, but will increment UseCounter
- // if appropriate. Ditto usages below.
- RaiseLanguageMode(SLOPPY);
- }
- } else {
- // End of the directive prologue.
- directive_prologue = false;
- RaiseLanguageMode(SLOPPY);
- }
- } else {
- RaiseLanguageMode(SLOPPY);
- }
-
- body->Add(stat, zone());
- }
-}
-
-
-Statement* Parser::ParseStatementListItem(bool* ok) {
- // (Ecma 262 6th Edition, 13.1):
- // StatementListItem:
- // Statement
- // Declaration
- const Token::Value peeked = peek();
- switch (peeked) {
- case Token::FUNCTION:
- return ParseHoistableDeclaration(NULL, false, ok);
- case Token::CLASS:
- Consume(Token::CLASS);
- return ParseClassDeclaration(NULL, false, ok);
- case Token::CONST:
- return ParseVariableStatement(kStatementListItem, NULL, ok);
- case Token::VAR:
- return ParseVariableStatement(kStatementListItem, NULL, ok);
- case Token::LET:
- if (IsNextLetKeyword()) {
- return ParseVariableStatement(kStatementListItem, NULL, ok);
- }
- break;
- case Token::ASYNC:
- if (allow_harmony_async_await() && PeekAhead() == Token::FUNCTION &&
- !scanner()->HasAnyLineTerminatorAfterNext()) {
- Consume(Token::ASYNC);
- return ParseAsyncFunctionDeclaration(NULL, false, ok);
- }
- /* falls through */
- default:
- break;
- }
- return ParseStatement(NULL, kAllowLabelledFunctionStatement, ok);
-}
-
-
Statement* Parser::ParseModuleItem(bool* ok) {
// ecma262/#prod-ModuleItem
// ModuleItem :
@@ -1486,139 +1359,6 @@ Statement* Parser::ParseExportDeclaration(bool* ok) {
return result;
}
-Statement* Parser::ParseStatement(ZoneList<const AstRawString*>* labels,
- AllowLabelledFunctionStatement allow_function,
- bool* ok) {
- // Statement ::
- // EmptyStatement
- // ...
-
- if (peek() == Token::SEMICOLON) {
- Next();
- return factory()->NewEmptyStatement(kNoSourcePosition);
- }
- return ParseSubStatement(labels, allow_function, ok);
-}
-
-Statement* Parser::ParseSubStatement(
- ZoneList<const AstRawString*>* labels,
- AllowLabelledFunctionStatement allow_function, bool* ok) {
- // Statement ::
- // Block
- // VariableStatement
- // EmptyStatement
- // ExpressionStatement
- // IfStatement
- // IterationStatement
- // ContinueStatement
- // BreakStatement
- // ReturnStatement
- // WithStatement
- // LabelledStatement
- // SwitchStatement
- // ThrowStatement
- // TryStatement
- // DebuggerStatement
-
- // Note: Since labels can only be used by 'break' and 'continue'
- // statements, which themselves are only valid within blocks,
- // iterations or 'switch' statements (i.e., BreakableStatements),
- // labels can be simply ignored in all other cases; except for
- // trivial labeled break statements 'label: break label' which is
- // parsed into an empty statement.
- switch (peek()) {
- case Token::LBRACE:
- return ParseBlock(labels, ok);
-
- case Token::SEMICOLON:
- Next();
- return factory()->NewEmptyStatement(kNoSourcePosition);
-
- case Token::IF:
- return ParseIfStatement(labels, ok);
-
- case Token::DO:
- return ParseDoWhileStatement(labels, ok);
-
- case Token::WHILE:
- return ParseWhileStatement(labels, ok);
-
- case Token::FOR:
- return ParseForStatement(labels, ok);
-
- case Token::CONTINUE:
- case Token::BREAK:
- case Token::RETURN:
- case Token::THROW:
- case Token::TRY: {
- // These statements must have their labels preserved in an enclosing
- // block
- if (labels == NULL) {
- return ParseStatementAsUnlabelled(labels, ok);
- } else {
- Block* result =
- factory()->NewBlock(labels, 1, false, kNoSourcePosition);
- Target target(&this->target_stack_, result);
- Statement* statement = ParseStatementAsUnlabelled(labels, CHECK_OK);
- if (result) result->statements()->Add(statement, zone());
- return result;
- }
- }
-
- case Token::WITH:
- return ParseWithStatement(labels, ok);
-
- case Token::SWITCH:
- return ParseSwitchStatement(labels, ok);
-
- case Token::FUNCTION:
- // FunctionDeclaration only allowed as a StatementListItem, not in
- // an arbitrary Statement position. Exceptions such as
- // ES#sec-functiondeclarations-in-ifstatement-statement-clauses
- // are handled by calling ParseScopedStatement rather than
- // ParseSubStatement directly.
- ReportMessageAt(scanner()->peek_location(),
- is_strict(language_mode())
- ? MessageTemplate::kStrictFunction
- : MessageTemplate::kSloppyFunction);
- *ok = false;
- return nullptr;
-
- case Token::DEBUGGER:
- return ParseDebuggerStatement(ok);
-
- case Token::VAR:
- return ParseVariableStatement(kStatement, NULL, ok);
-
- default:
- return ParseExpressionOrLabelledStatement(labels, allow_function, ok);
- }
-}
-
-Statement* Parser::ParseStatementAsUnlabelled(
- ZoneList<const AstRawString*>* labels, bool* ok) {
- switch (peek()) {
- case Token::CONTINUE:
- return ParseContinueStatement(ok);
-
- case Token::BREAK:
- return ParseBreakStatement(labels, ok);
-
- case Token::RETURN:
- return ParseReturnStatement(ok);
-
- case Token::THROW:
- return ParseThrowStatement(ok);
-
- case Token::TRY:
- return ParseTryStatement(ok);
-
- default:
- UNREACHABLE();
- return NULL;
- }
-}
-
VariableProxy* Parser::NewUnresolved(const AstRawString* name, int begin_pos,
int end_pos, Variable::Kind kind) {
return scope()->NewUnresolved(factory(), name, begin_pos, end_pos, kind);
@@ -1877,7 +1617,7 @@ Block* Parser::ParseBlock(ZoneList<const AstRawString*>* labels, bool* ok) {
{
BlockState block_state(&scope_state_);
block_state.set_start_position(scanner()->location().beg_pos);
- Target target(&this->target_stack_, body);
+ ParserTarget target(this, body);
while (peek() != Token::RBRACE) {
Statement* stat = ParseStatementListItem(CHECK_OK);
@@ -2349,7 +2089,7 @@ Statement* Parser::ParseSwitchStatement(ZoneList<const AstRawString*>* labels,
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);
+ ParserTarget target(this, switch_statement);
Expression* tag_read = factory()->NewVariableProxy(tag_variable);
@@ -2455,7 +2195,7 @@ TryStatement* Parser::ParseTryStatement(bool* ok) {
{
BlockState block_state(&scope_state_);
block_state.set_start_position(scanner()->location().beg_pos);
- Target target(&this->target_stack_, catch_block);
+ ParserTarget target(this, catch_block);
const AstRawString* name = ast_value_factory()->dot_catch_string();
Expression* pattern = nullptr;
@@ -2594,7 +2334,7 @@ DoWhileStatement* Parser::ParseDoWhileStatement(
DoWhileStatement* loop =
factory()->NewDoWhileStatement(labels, peek_position());
- Target target(&this->target_stack_, loop);
+ ParserTarget target(this, loop);
Expect(Token::DO, CHECK_OK);
Statement* body = ParseScopedStatement(NULL, true, CHECK_OK);
@@ -2621,7 +2361,7 @@ WhileStatement* Parser::ParseWhileStatement(
// 'while' '(' Expression ')' Statement
WhileStatement* loop = factory()->NewWhileStatement(labels, peek_position());
- Target target(&this->target_stack_, loop);
+ ParserTarget target(this, loop);
Expect(Token::WHILE, CHECK_OK);
Expect(Token::LPAREN, CHECK_OK);
@@ -3069,7 +2809,7 @@ Statement* Parser::ParseScopedStatement(ZoneList<const AstRawString*>* labels,
bool legacy, bool* ok) {
if (is_strict(language_mode()) || peek() != Token::FUNCTION ||
(legacy && allow_harmony_restrictive_declarations())) {
- return ParseSubStatement(labels, kDisallowLabelledFunctionStatement, ok);
+ return ParseStatement(labels, kDisallowLabelledFunctionStatement, ok);
} else {
if (legacy) {
++use_counts_[v8::Isolate::kLegacyFunctionDeclaration];
@@ -3178,7 +2918,7 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
Variable* temp = NewTemporary(ast_value_factory()->dot_for_string());
ForEachStatement* loop =
factory()->NewForEachStatement(mode, labels, stmt_pos);
- Target target(&this->target_stack_, loop);
+ ParserTarget target(this, loop);
int each_keyword_position = scanner()->location().beg_pos;
@@ -3324,7 +3064,7 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
ForEachStatement* loop =
factory()->NewForEachStatement(mode, labels, stmt_pos);
- Target target(&this->target_stack_, loop);
+ ParserTarget target(this, loop);
int each_keyword_position = scanner()->location().beg_pos;
@@ -3356,7 +3096,7 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
// Standard 'for' loop
ForStatement* loop = factory()->NewForStatement(labels, stmt_pos);
- Target target(&this->target_stack_, loop);
+ ParserTarget target(this, loop);
// Parsed initializer at this point.
Expect(Token::SEMICOLON, CHECK_OK);
@@ -4815,7 +4555,7 @@ void Parser::InsertSloppyBlockFunctionVarBindings(DeclarationScope* scope,
// Parser support
bool Parser::TargetStackContainsLabel(const AstRawString* label) {
- for (Target* t = target_stack_; t != NULL; t = t->previous()) {
+ for (ParserTarget* t = target_stack_; t != NULL; t = t->previous()) {
if (ContainsLabel(t->statement()->labels(), label)) return true;
}
return false;
@@ -4825,7 +4565,7 @@ bool Parser::TargetStackContainsLabel(const AstRawString* label) {
BreakableStatement* Parser::LookupBreakTarget(const AstRawString* label,
bool* ok) {
bool anonymous = label == NULL;
- for (Target* t = target_stack_; t != NULL; t = t->previous()) {
+ for (ParserTarget* t = target_stack_; t != NULL; t = t->previous()) {
BreakableStatement* stat = t->statement();
if ((anonymous && stat->is_target_for_anonymous()) ||
(!anonymous && ContainsLabel(stat->labels(), label))) {
@@ -4839,7 +4579,7 @@ BreakableStatement* Parser::LookupBreakTarget(const AstRawString* label,
IterationStatement* Parser::LookupContinueTarget(const AstRawString* label,
bool* ok) {
bool anonymous = label == NULL;
- for (Target* t = target_stack_; t != NULL; t = t->previous()) {
+ for (ParserTarget* t = target_stack_; t != NULL; t = t->previous()) {
IterationStatement* stat = t->statement()->AsIterationStatement();
if (stat == NULL) continue;
@@ -5233,10 +4973,12 @@ void Parser::SetLanguageMode(Scope* scope, LanguageMode mode) {
scope->SetLanguageMode(mode);
}
-
-void Parser::RaiseLanguageMode(LanguageMode mode) {
- LanguageMode old = scope()->language_mode();
- SetLanguageMode(scope(), old > mode ? old : mode);
+void Parser::SetAsmModule() {
+ // Store the usage count; The actual use counter on the isolate is
+ // incremented after parsing is done.
+ ++use_counts_[v8::Isolate::kUseAsm];
+ DCHECK(scope()->is_declaration_scope());
+ scope()->AsDeclarationScope()->set_asm_module();
}
void Parser::MarkCollectedTailCallExpressions() {
« no previous file with comments | « src/parsing/parser.h ('k') | src/parsing/parser-base.h » ('j') | src/parsing/parser-base.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698