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

Unified Diff: src/parsing/preparser.cc

Issue 2313703002: Revert of [parser] Refactor of Parse*Statement*, part 1 (Closed)
Patch Set: 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
« no previous file with comments | « src/parsing/preparser.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/parsing/preparser.cc
diff --git a/src/parsing/preparser.cc b/src/parsing/preparser.cc
index 4a3f680f035d1384bb8d445bf5b40ec5b4ee2910..369ff2415efb8dbe3351b73dfb3c818147460c64 100644
--- a/src/parsing/preparser.cc
+++ b/src/parsing/preparser.cc
@@ -122,19 +122,223 @@
// it is used) are generally omitted.
+PreParser::Statement PreParser::ParseStatementListItem(bool* ok) {
+ // ECMA 262 6th Edition
+ // StatementListItem[Yield, Return] :
+ // Statement[?Yield, ?Return]
+ // Declaration[?Yield]
+ //
+ // Declaration[Yield] :
+ // HoistableDeclaration[?Yield]
+ // ClassDeclaration[?Yield]
+ // LexicalDeclaration[In, ?Yield]
+ //
+ // HoistableDeclaration[Yield, Default] :
+ // FunctionDeclaration[?Yield, ?Default]
+ // GeneratorDeclaration[?Yield, ?Default]
+ //
+ // LexicalDeclaration[In, Yield] :
+ // LetOrConst BindingList[?In, ?Yield] ;
+
+ switch (peek()) {
+ case Token::FUNCTION:
+ return ParseHoistableDeclaration(ok);
+ case Token::CLASS:
+ return ParseClassDeclaration(ok);
+ case Token::CONST:
+ return ParseVariableStatement(kStatementListItem, ok);
+ case Token::LET:
+ if (IsNextLetKeyword()) {
+ return ParseVariableStatement(kStatementListItem, ok);
+ }
+ break;
+ case Token::ASYNC:
+ if (allow_harmony_async_await() && PeekAhead() == Token::FUNCTION &&
+ !scanner()->HasAnyLineTerminatorAfterNext()) {
+ Consume(Token::ASYNC);
+ return ParseAsyncFunctionDeclaration(ok);
+ }
+ /* falls through */
+ default:
+ break;
+ }
+ return ParseStatement(kAllowLabelledFunctionStatement, ok);
+}
+
+PreParser::LazyParsingResult PreParser::ParseStatementList(int end_token,
+ bool may_abort,
+ bool* ok) {
+ // SourceElements ::
+ // (Statement)* <end_token>
+
+ int count_statements = 0;
+
+ bool directive_prologue = true;
+ while (peek() != end_token) {
+ if (directive_prologue && peek() != Token::STRING) {
+ directive_prologue = false;
+ }
+ bool starts_with_identifier = peek() == Token::IDENTIFIER;
+ Scanner::Location token_loc = scanner()->peek_location();
+ Statement statement =
+ ParseStatementListItem(CHECK_OK_VALUE(kLazyParsingComplete));
+
+ if (directive_prologue) {
+ bool use_strict_found = statement.IsUseStrictLiteral();
+
+ if (use_strict_found) {
+ scope()->SetLanguageMode(
+ static_cast<LanguageMode>(scope()->language_mode() | STRICT));
+ } else if (!statement.IsStringLiteral()) {
+ directive_prologue = false;
+ }
+
+ 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
+ ReportMessageAt(token_loc,
+ MessageTemplate::kIllegalLanguageModeDirective,
+ "use strict");
+ *ok = false;
+ return kLazyParsingComplete;
+ }
+ }
+
+ // If we're allowed to reset to a bookmark, we will do so when we see a long
+ // and trivial function.
+ // Our current definition of 'long and trivial' is:
+ // - over 200 statements
+ // - all starting with an identifier (i.e., no if, for, while, etc.)
+ if (may_abort) {
+ if (!starts_with_identifier) {
+ may_abort = false;
+ } else if (++count_statements > kLazyParseTrialLimit) {
+ return kLazyParsingAborted;
+ }
+ }
+ }
+ return kLazyParsingComplete;
+}
+
+
+PreParser::Statement PreParser::ParseStatement(
+ AllowLabelledFunctionStatement allow_function, bool* ok) {
+ // Statement ::
+ // EmptyStatement
+ // ...
+
+ if (peek() == Token::SEMICOLON) {
+ Next();
+ return Statement::Default();
+ }
+ return ParseSubStatement(allow_function, ok);
+}
+
PreParser::Statement PreParser::ParseScopedStatement(bool legacy, bool* ok) {
if (is_strict(language_mode()) || peek() != Token::FUNCTION ||
(legacy && allow_harmony_restrictive_declarations())) {
- return ParseStatement(nullptr, kDisallowLabelledFunctionStatement, ok);
+ return ParseSubStatement(kDisallowLabelledFunctionStatement, ok);
} else {
BlockState block_state(&scope_state_);
return ParseFunctionDeclaration(ok);
}
}
+PreParser::Statement PreParser::ParseSubStatement(
+ 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.
+
+ // Keep the source position of the statement
+ switch (peek()) {
+ case Token::LBRACE:
+ return ParseBlock(ok);
+
+ case Token::SEMICOLON:
+ Next();
+ return Statement::Default();
+
+ case Token::IF:
+ return ParseIfStatement(ok);
+
+ case Token::DO:
+ return ParseDoWhileStatement(ok);
+
+ case Token::WHILE:
+ return ParseWhileStatement(ok);
+
+ case Token::FOR:
+ return ParseForStatement(ok);
+
+ case Token::CONTINUE:
+ return ParseContinueStatement(ok);
+
+ case Token::BREAK:
+ return ParseBreakStatement(ok);
+
+ case Token::RETURN:
+ return ParseReturnStatement(ok);
+
+ case Token::WITH:
+ return ParseWithStatement(ok);
+
+ case Token::SWITCH:
+ return ParseSwitchStatement(ok);
+
+ case Token::THROW:
+ return ParseThrowStatement(ok);
+
+ case Token::TRY:
+ return ParseTryStatement(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 Statement::Default();
+
+ case Token::DEBUGGER:
+ return ParseDebuggerStatement(ok);
+
+ case Token::VAR:
+ return ParseVariableStatement(kStatement, ok);
+
+ default:
+ return ParseExpressionOrLabelledStatement(allow_function, ok);
+ }
+}
+
PreParser::Statement PreParser::ParseHoistableDeclaration(
- int pos, ParseFunctionFlags flags, ZoneList<const AstRawString*>* names,
- bool default_export, bool* ok) {
+ int pos, ParseFunctionFlags flags, bool* ok) {
const bool is_generator = flags & ParseFunctionFlags::kIsGenerator;
const bool is_async = flags & ParseFunctionFlags::kIsAsync;
DCHECK(!is_generator || !is_async);
@@ -154,8 +358,7 @@
return Statement::FunctionDeclaration();
}
-PreParser::Statement PreParser::ParseAsyncFunctionDeclaration(
- ZoneList<const AstRawString*>* names, bool default_export, bool* ok) {
+PreParser::Statement PreParser::ParseAsyncFunctionDeclaration(bool* ok) {
// AsyncFunctionDeclaration ::
// async [no LineTerminator here] function BindingIdentifier[Await]
// ( FormalParameters[Await] ) { AsyncFunctionBody }
@@ -163,11 +366,10 @@
int pos = position();
Expect(Token::FUNCTION, CHECK_OK);
ParseFunctionFlags flags = ParseFunctionFlags::kIsAsync;
- return ParseHoistableDeclaration(pos, flags, names, default_export, ok);
-}
-
-PreParser::Statement PreParser::ParseHoistableDeclaration(
- ZoneList<const AstRawString*>* names, bool default_export, bool* ok) {
+ return ParseHoistableDeclaration(pos, flags, ok);
+}
+
+PreParser::Statement PreParser::ParseHoistableDeclaration(bool* ok) {
// FunctionDeclaration ::
// 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
// GeneratorDeclaration ::
@@ -180,11 +382,13 @@
if (Check(Token::MUL)) {
flags |= ParseFunctionFlags::kIsGenerator;
}
- return ParseHoistableDeclaration(pos, flags, names, default_export, ok);
-}
-
-PreParser::Statement PreParser::ParseClassDeclaration(
- ZoneList<const AstRawString*>* names, bool default_export, bool* ok) {
+ return ParseHoistableDeclaration(pos, flags, ok);
+}
+
+
+PreParser::Statement PreParser::ParseClassDeclaration(bool* ok) {
+ Expect(Token::CLASS, CHECK_OK);
+
int pos = position();
bool is_strict_reserved = false;
Identifier name =
@@ -195,8 +399,8 @@
return Statement::Default();
}
-PreParser::Statement PreParser::ParseBlock(
- ZoneList<const AstRawString*>* labels, bool* ok) {
+
+PreParser::Statement PreParser::ParseBlock(bool* ok) {
// Block ::
// '{' StatementList '}'
@@ -212,14 +416,15 @@
return final;
}
+
PreParser::Statement PreParser::ParseVariableStatement(
VariableDeclarationContext var_context,
- ZoneList<const AstRawString*>* names, bool* ok) {
+ bool* ok) {
// VariableStatement ::
// VariableDeclarations ';'
Statement result =
- ParseVariableDeclarations(var_context, nullptr, names, CHECK_OK);
+ ParseVariableDeclarations(var_context, nullptr, nullptr, CHECK_OK);
ExpectSemicolon(CHECK_OK);
return result;
}
@@ -237,11 +442,10 @@
return Statement::Default();
}
}
- return ParseHoistableDeclaration(pos, flags, nullptr, false, ok);
+ return ParseHoistableDeclaration(pos, flags, ok);
}
PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(
- ZoneList<const AstRawString*>* names,
AllowLabelledFunctionStatement allow_function, bool* ok) {
// ExpressionStatement | LabelledStatement ::
// Expression ';'
@@ -285,7 +489,7 @@
}
}
Statement statement =
- ParseStatement(nullptr, kDisallowLabelledFunctionStatement, ok);
+ ParseStatement(kDisallowLabelledFunctionStatement, ok);
return statement.IsJumpStatement() ? Statement::Default() : statement;
// Preparsing is disabled for extensions (because the extension details
// aren't passed to lazily compiled functions), so we don't
@@ -296,8 +500,8 @@
return Statement::ExpressionStatement(expr);
}
-PreParser::Statement PreParser::ParseIfStatement(
- ZoneList<const AstRawString*>* labels, bool* ok) {
+
+PreParser::Statement PreParser::ParseIfStatement(bool* ok) {
// IfStatement ::
// 'if' '(' Expression ')' Statement ('else' Statement)?
@@ -335,8 +539,8 @@
return Statement::Jump();
}
-PreParser::Statement PreParser::ParseBreakStatement(
- ZoneList<const AstRawString*>* labels, bool* ok) {
+
+PreParser::Statement PreParser::ParseBreakStatement(bool* ok) {
// BreakStatement ::
// 'break' [no line terminator] Identifier? ';'
@@ -389,8 +593,8 @@
return Statement::Jump();
}
-PreParser::Statement PreParser::ParseWithStatement(
- ZoneList<const AstRawString*>* labels, bool* ok) {
+
+PreParser::Statement PreParser::ParseWithStatement(bool* ok) {
// WithStatement ::
// 'with' '(' Expression ')' Statement
Expect(Token::WITH, CHECK_OK);
@@ -409,8 +613,8 @@
return Statement::Default();
}
-PreParser::Statement PreParser::ParseSwitchStatement(
- ZoneList<const AstRawString*>* labels, bool* ok) {
+
+PreParser::Statement PreParser::ParseSwitchStatement(bool* ok) {
// SwitchStatement ::
// 'switch' '(' Expression ')' '{' CaseClause* '}'
@@ -445,8 +649,8 @@
return Statement::Default();
}
-PreParser::Statement PreParser::ParseDoWhileStatement(
- ZoneList<const AstRawString*>* labels, bool* ok) {
+
+PreParser::Statement PreParser::ParseDoWhileStatement(bool* ok) {
// DoStatement ::
// 'do' Statement 'while' '(' Expression ')' ';'
@@ -460,8 +664,8 @@
return Statement::Default();
}
-PreParser::Statement PreParser::ParseWhileStatement(
- ZoneList<const AstRawString*>* labels, bool* ok) {
+
+PreParser::Statement PreParser::ParseWhileStatement(bool* ok) {
// WhileStatement ::
// 'while' '(' Expression ')' Statement
@@ -473,8 +677,8 @@
return Statement::Default();
}
-PreParser::Statement PreParser::ParseForStatement(
- ZoneList<const AstRawString*>* labels, bool* ok) {
+
+PreParser::Statement PreParser::ParseForStatement(bool* ok) {
// ForStatement ::
// 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
@@ -640,7 +844,7 @@
{
ReturnExprScope no_tail_calls(function_state_,
ReturnExprContext::kInsideTryBlock);
- ParseBlock(nullptr, CHECK_OK);
+ ParseBlock(CHECK_OK);
}
Token::Value tok = peek();
@@ -666,7 +870,7 @@
BlockState block_state(&scope_state_, catch_scope);
{
BlockState block_state(&scope_state_);
- ParseBlock(nullptr, CHECK_OK);
+ ParseBlock(CHECK_OK);
}
}
catch_block_exists = true;
@@ -674,7 +878,7 @@
}
if (tok == Token::FINALLY) {
Consume(Token::FINALLY);
- ParseBlock(nullptr, CHECK_OK);
+ ParseBlock(CHECK_OK);
if (FLAG_harmony_explicit_tailcalls && catch_block_exists &&
tail_call_expressions_in_catch_block.has_explicit_tail_calls()) {
// TODO(ishell): update chapter number.
@@ -715,7 +919,6 @@
// '(' FormalParameterList? ')' '{' FunctionBody '}'
// Parse function body.
- PreParserStatementList body;
bool outer_is_script_scope = scope()->is_script_scope();
DeclarationScope* function_scope = NewFunctionScope(kind);
function_scope->SetLanguageMode(language_mode);
@@ -744,7 +947,7 @@
if (is_lazily_parsed) {
ParseLazyFunctionLiteralBody(false, CHECK_OK);
} else {
- ParseStatementList(body, Token::RBRACE, CHECK_OK);
+ ParseStatementList(Token::RBRACE, CHECK_OK);
}
Expect(Token::RBRACE, CHECK_OK);
@@ -799,9 +1002,8 @@
PreParser::LazyParsingResult PreParser::ParseLazyFunctionLiteralBody(
bool may_abort, bool* ok) {
int body_start = position();
- PreParserStatementList body;
LazyParsingResult result = ParseStatementList(
- body, Token::RBRACE, may_abort, CHECK_OK_VALUE(kLazyParsingComplete));
+ Token::RBRACE, may_abort, CHECK_OK_VALUE(kLazyParsingComplete));
if (result == kLazyParsingAborted) return result;
// Position right after terminal '}'.
« no previous file with comments | « src/parsing/preparser.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698