[parser] Reduce reliance on has_error()

Instead we can typically check whether the expression or statement we just
parsed indicate failure.

Bug: v8:8363, v8:7926
Change-Id: I477511f9f2f0e615a07285db858a237af8478edc
Reviewed-on: https://chromium-review.googlesource.com/c/1323553
Reviewed-by: Igor Sheludko <ishell@chromium.org>
Commit-Queue: Toon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57322}
This commit is contained in:
Toon Verwaest 2018-11-07 18:00:35 +01:00 committed by Commit Bot
parent ba84cfee49
commit 1d0385cdd8
3 changed files with 27 additions and 22 deletions

View File

@ -1936,7 +1936,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseArrayLiteral() {
values.Add(elem); values.Add(elem);
if (peek() != Token::RBRACK) { if (peek() != Token::RBRACK) {
Expect(Token::COMMA); Expect(Token::COMMA);
if (has_error()) return impl()->FailureExpression(); if (elem->IsFailureExpression()) return elem;
} }
} }
@ -2527,7 +2527,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseObjectLiteral() {
bool is_rest_property = false; bool is_rest_property = false;
ObjectLiteralPropertyT property = ParseObjectPropertyDefinition( ObjectLiteralPropertyT property = ParseObjectPropertyDefinition(
&checker, &is_computed_name, &is_rest_property); &checker, &is_computed_name, &is_rest_property);
if (has_error()) return impl()->FailureExpression(); if (impl()->IsNull(property)) return impl()->FailureExpression();
if (is_computed_name) { if (is_computed_name) {
has_computed_names = true; has_computed_names = true;
@ -4127,7 +4127,6 @@ ParserBase<Impl>::ParseArrowFunctionLiteral(
// Validate parameter names. We can do this only after preparsing the // Validate parameter names. We can do this only after preparsing the
// function, since the function can declare itself strict. // function, since the function can declare itself strict.
ValidateFormalParameters(language_mode(), false); ValidateFormalParameters(language_mode(), false);
if (has_error()) return impl()->FailureExpression();
DCHECK_NULL(produced_preparsed_scope_data); DCHECK_NULL(produced_preparsed_scope_data);
@ -4541,11 +4540,11 @@ ParserBase<Impl>::ParseStatementList(StatementListT* body,
} }
StatementT stat = ParseStatementListItem(); StatementT stat = ParseStatementListItem();
if (impl()->IsNull(stat)) return kLazyParsingComplete;
body->Add(stat); body->Add(stat);
may_abort = false; may_abort = false;
if (has_error()) return kLazyParsingComplete;
if (!impl()->IsStringLiteral(stat)) break; if (!impl()->IsStringLiteral(stat)) break;
if (use_strict) { if (use_strict) {
@ -4591,7 +4590,7 @@ ParserBase<Impl>::ParseStatementList(StatementListT* body,
while (peek() != end_token) { while (peek() != end_token) {
StatementT stat = ParseStatementListItem(); StatementT stat = ParseStatementListItem();
if (has_error()) return kLazyParsingComplete; if (impl()->IsNull(stat)) return kLazyParsingComplete;
if (stat->IsEmptyStatement()) continue; if (stat->IsEmptyStatement()) continue;
body->Add(stat); body->Add(stat);
} }
@ -4772,7 +4771,7 @@ typename ParserBase<Impl>::BlockT ParserBase<Impl>::ParseBlock(
while (peek() != Token::RBRACE) { while (peek() != Token::RBRACE) {
StatementT stat = ParseStatementListItem(); StatementT stat = ParseStatementListItem();
RETURN_IF_PARSE_ERROR; if (impl()->IsNull(stat)) return body;
if (stat->IsEmptyStatement()) continue; if (stat->IsEmptyStatement()) continue;
statements.Add(stat); statements.Add(stat);
} }
@ -4917,6 +4916,7 @@ ParserBase<Impl>::ParseExpressionOrLabelledStatement(
// Parsed expression statement, followed by semicolon. // Parsed expression statement, followed by semicolon.
ExpectSemicolon(); ExpectSemicolon();
if (expr->IsFailureExpression()) return impl()->NullStatement();
return factory()->NewExpressionStatement(expr, pos); return factory()->NewExpressionStatement(expr, pos);
} }
@ -5228,7 +5228,7 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseSwitchStatement(
while (peek() != Token::CASE && peek() != Token::DEFAULT && while (peek() != Token::CASE && peek() != Token::DEFAULT &&
peek() != Token::RBRACE) { peek() != Token::RBRACE) {
StatementT stat = ParseStatementListItem(); StatementT stat = ParseStatementListItem();
RETURN_IF_PARSE_ERROR; if (impl()->IsNull(stat)) return stat;
if (stat->IsEmptyStatement()) continue; if (stat->IsEmptyStatement()) continue;
statements.Add(stat); statements.Add(stat);
} }

View File

@ -899,7 +899,7 @@ void Parser::ParseModuleItemList(ScopedPtrList<Statement>* body) {
DCHECK(scope()->is_module_scope()); DCHECK(scope()->is_module_scope());
while (peek() != Token::EOS) { while (peek() != Token::EOS) {
Statement* stat = ParseModuleItem(); Statement* stat = ParseModuleItem();
if (has_error()) return; if (stat == nullptr) return;
if (stat->IsEmptyStatement()) continue; if (stat->IsEmptyStatement()) continue;
body->Add(stat); body->Add(stat);
} }
@ -955,8 +955,10 @@ ZoneChunkList<Parser::ExportClauseData>* Parser::ParseExportClause(
} }
export_data->push_back({export_name, local_name, location}); export_data->push_back({export_name, local_name, location});
if (peek() == Token::RBRACE) break; if (peek() == Token::RBRACE) break;
Expect(Token::COMMA); if (V8_UNLIKELY(!Check(Token::COMMA))) {
if (has_error()) break; ReportUnexpectedToken(Next());
break;
}
} }
Expect(Token::RBRACE); Expect(Token::RBRACE);
@ -1176,13 +1178,13 @@ Statement* Parser::ParseExportDefault() {
} }
} }
if (has_error()) return nullptr; if (result != nullptr) {
DCHECK_EQ(local_names.length(), 1); DCHECK_EQ(local_names.length(), 1);
module()->AddExport(local_names.first(), module()->AddExport(local_names.first(),
ast_value_factory()->default_string(), default_loc, ast_value_factory()->default_string(), default_loc,
zone()); zone());
}
DCHECK_NOT_NULL(result);
return result; return result;
} }
@ -1686,7 +1688,7 @@ void Parser::ParseAndRewriteGeneratorFunctionBody(
Expression* initial_yield = BuildInitialYield(pos, kind); Expression* initial_yield = BuildInitialYield(pos, kind);
body->Add( body->Add(
factory()->NewExpressionStatement(initial_yield, kNoSourcePosition)); factory()->NewExpressionStatement(initial_yield, kNoSourcePosition));
ParseStatementList(body, Token::RBRACE, !has_error()); ParseStatementList(body, Token::RBRACE);
} }
void Parser::ParseAndRewriteAsyncGeneratorFunctionBody( void Parser::ParseAndRewriteAsyncGeneratorFunctionBody(
@ -1719,7 +1721,7 @@ void Parser::ParseAndRewriteAsyncGeneratorFunctionBody(
Expression* initial_yield = BuildInitialYield(pos, kind); Expression* initial_yield = BuildInitialYield(pos, kind);
statements.Add( statements.Add(
factory()->NewExpressionStatement(initial_yield, kNoSourcePosition)); factory()->NewExpressionStatement(initial_yield, kNoSourcePosition));
ParseStatementList(&statements, Token::RBRACE, !has_error()); ParseStatementList(&statements, Token::RBRACE);
// Don't create iterator result for async generators, as the resume methods // Don't create iterator result for async generators, as the resume methods
// will create it. // will create it.
@ -2587,9 +2589,9 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
scope->SetScopeName(function_name); scope->SetScopeName(function_name);
#endif #endif
if (!is_wrapped) { if (!is_wrapped && V8_UNLIKELY(!Check(Token::LPAREN))) {
Expect(Token::LPAREN); ReportUnexpectedToken(Next());
if (has_error()) return nullptr; return nullptr;
} }
scope->set_start_position(position()); scope->set_start_position(position());

View File

@ -210,6 +210,9 @@ class PreParserExpression {
} }
bool IsNull() const { return TypeField::decode(code_) == kNull; } bool IsNull() const { return TypeField::decode(code_) == kNull; }
bool IsFailureExpression() const {
return TypeField::decode(code_) == kFailure;
}
bool IsIdentifier() const { bool IsIdentifier() const {
return TypeField::decode(code_) == kIdentifierExpression; return TypeField::decode(code_) == kIdentifierExpression;