Commit ee48d322 authored by nikolaos's avatar nikolaos Committed by Commit bot

[parser] Refactor some CHECK_OK calls

R=adamk@chromium.org, littledan@chromium.org
BUG=
LOG=N

Review-Url: https://codereview.chromium.org/2154253002
Cr-Commit-Position: refs/heads/master@{#37851}
parent 173313e2
......@@ -119,6 +119,28 @@ struct FormalParametersBase {
};
// ----------------------------------------------------------------------------
// The CHECK_OK macro is a convenient macro to enforce error
// handling for functions that may fail (by returning !*ok).
//
// CAUTION: This macro appends extra statements after a call,
// thus it must never be used where only a single statement
// is correct (e.g. an if statement branch w/o braces)!
#define CHECK_OK ok); \
if (!*ok) return this->EmptyExpression(); \
((void)0
#define DUMMY ) // to make indentation work
#undef DUMMY
// Used in functions where the return type is not ExpressionT.
#define CHECK_OK_CUSTOM(x) ok); \
if (!*ok) return this->x(); \
((void)0
#define DUMMY ) // to make indentation work
#undef DUMMY
// Common base class shared between parser and pre-parser. Traits encapsulate
// the differences between Parser and PreParser:
......@@ -670,6 +692,9 @@ class ParserBase : public Traits {
Expect(Token::SEMICOLON, ok);
}
// A dummy function, just useful as an argument to CHECK_OK_CUSTOM.
static void Void() {}
bool is_any_identifier(Token::Value token) {
return token == Token::IDENTIFIER || token == Token::ENUM ||
token == Token::AWAIT || token == Token::ASYNC ||
......@@ -695,8 +720,7 @@ class ParserBase : public Traits {
const char* full_name, int pos, bool* ok);
void ExpectContextualKeyword(Vector<const char> keyword, bool* ok) {
Expect(Token::IDENTIFIER, ok);
if (!*ok) return;
Expect(Token::IDENTIFIER, CHECK_OK_CUSTOM(Void));
if (!scanner()->is_literal_contextual_keyword(keyword)) {
ReportUnexpectedToken(scanner()->current_token());
*ok = false;
......@@ -1311,14 +1335,12 @@ template <class Traits>
typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier(
AllowRestrictedIdentifiers allow_restricted_identifiers, bool* ok) {
ExpressionClassifier classifier(this);
auto result = ParseAndClassifyIdentifier(&classifier, ok);
if (!*ok) return Traits::EmptyIdentifier();
auto result =
ParseAndClassifyIdentifier(&classifier, CHECK_OK_CUSTOM(EmptyIdentifier));
if (allow_restricted_identifiers == kDontAllowRestrictedIdentifiers) {
ValidateAssignmentPattern(&classifier, ok);
if (!*ok) return Traits::EmptyIdentifier();
ValidateBindingPattern(&classifier, ok);
if (!*ok) return Traits::EmptyIdentifier();
ValidateAssignmentPattern(&classifier, CHECK_OK_CUSTOM(EmptyIdentifier));
ValidateBindingPattern(&classifier, CHECK_OK_CUSTOM(EmptyIdentifier));
}
return result;
......@@ -1468,19 +1490,6 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseRegExpLiteral(
}
#define CHECK_OK ok); \
if (!*ok) return this->EmptyExpression(); \
((void)0
#define DUMMY ) // to make indentation work
#undef DUMMY
// Used in functions where the return type is not ExpressionT.
#define CHECK_OK_CUSTOM(x) ok); \
if (!*ok) return this->x(); \
((void)0
#define DUMMY ) // to make indentation work
#undef DUMMY
template <class Traits>
typename ParserBase<Traits>::ExpressionT
ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
......@@ -3084,8 +3093,7 @@ void ParserBase<Traits>::ExpectMetaProperty(Vector<const char> property_name,
const char* full_name, int pos,
bool* ok) {
Consume(Token::PERIOD);
ExpectContextualKeyword(property_name, ok);
if (!*ok) return;
ExpectContextualKeyword(property_name, CHECK_OK_CUSTOM(Void));
if (scanner()->literal_contains_escapes()) {
Traits::ReportMessageAt(
Scanner::Location(pos, scanner()->location().end_pos),
......@@ -3194,27 +3202,23 @@ void ParserBase<Traits>::ParseFormalParameter(
// BindingElement[?Yield, ?GeneratorParameter]
bool is_rest = parameters->has_rest;
ExpressionT pattern = ParsePrimaryExpression(classifier, ok);
if (!*ok) return;
ValidateBindingPattern(classifier, ok);
if (!*ok) return;
ExpressionT pattern =
ParsePrimaryExpression(classifier, CHECK_OK_CUSTOM(Void));
ValidateBindingPattern(classifier, CHECK_OK_CUSTOM(Void));
if (!Traits::IsIdentifier(pattern)) {
parameters->is_simple = false;
ValidateFormalParameterInitializer(classifier, ok);
if (!*ok) return;
ValidateFormalParameterInitializer(classifier, CHECK_OK_CUSTOM(Void));
classifier->RecordNonSimpleParameter();
}
ExpressionT initializer = Traits::EmptyExpression();
if (!is_rest && Check(Token::ASSIGN)) {
ExpressionClassifier init_classifier(this);
initializer = ParseAssignmentExpression(true, &init_classifier, ok);
if (!*ok) return;
Traits::RewriteNonPattern(&init_classifier, ok);
ValidateFormalParameterInitializer(&init_classifier, ok);
if (!*ok) return;
initializer = ParseAssignmentExpression(true, &init_classifier,
CHECK_OK_CUSTOM(Void));
Traits::RewriteNonPattern(&init_classifier, CHECK_OK_CUSTOM(Void));
ValidateFormalParameterInitializer(&init_classifier, CHECK_OK_CUSTOM(Void));
parameters->is_simple = false;
init_classifier.Discard();
classifier->RecordNonSimpleParameter();
......@@ -3251,8 +3255,7 @@ void ParserBase<Traits>::ParseFormalParameterList(
return;
}
parameters->has_rest = Check(Token::ELLIPSIS);
ParseFormalParameter(parameters, classifier, ok);
if (!*ok) return;
ParseFormalParameter(parameters, classifier, CHECK_OK_CUSTOM(Void));
if (parameters->has_rest) {
parameters->is_simple = false;
......
......@@ -314,6 +314,13 @@ class TargetScope BASE_EMBEDDED {
#define DUMMY ) // to make indentation work
#undef DUMMY
// Used in functions where the return type is not ExpressionT.
#define CHECK_OK_CUSTOM(x) ok); \
if (!*ok) return this->x(); \
((void)0
#define DUMMY ) // to make indentation work
#undef DUMMY
#define CHECK_FAILED /**/); \
if (failed_) return NULL; \
((void)0
......@@ -3876,8 +3883,7 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
int lhs_end_pos = scanner()->location().end_pos;
ForEachStatement::VisitMode mode = ForEachStatement::ENUMERATE;
bool is_for_each = CheckInOrOf(&mode, ok);
if (!*ok) return nullptr;
bool is_for_each = CheckInOrOf(&mode, CHECK_OK);
bool is_destructuring = is_for_each && (expression->IsArrayLiteral() ||
expression->IsObjectLiteral());
......@@ -4089,8 +4095,8 @@ void ParserTraits::ParseArrowFunctionFormalParameters(
Expression* left = binop->left();
Expression* right = binop->right();
int comma_pos = binop->position();
ParseArrowFunctionFormalParameters(parameters, left, comma_pos, ok);
if (!*ok) return;
ParseArrowFunctionFormalParameters(parameters, left, comma_pos,
CHECK_OK_CUSTOM(Void));
// LHS of comma expression should be unparenthesized.
expr = right;
}
......@@ -4169,14 +4175,12 @@ void Parser::DesugarAsyncFunctionBody(const AstRawString* function_name,
Expression* return_value = nullptr;
if (body_type == FunctionBody::Normal) {
ParseStatementList(inner_body, Token::RBRACE, ok);
if (!*ok) return;
ParseStatementList(inner_body, Token::RBRACE, CHECK_OK_CUSTOM(Void));
return_value = factory()->NewUndefinedLiteral(kNoSourcePosition);
} else {
return_value = ParseAssignmentExpression(accept_IN, classifier, ok);
if (!*ok) return;
ParserTraits::RewriteNonPattern(classifier, ok);
if (!*ok) return;
return_value =
ParseAssignmentExpression(accept_IN, classifier, CHECK_OK_CUSTOM(Void));
ParserTraits::RewriteNonPattern(classifier, CHECK_OK_CUSTOM(Void));
}
return_value = BuildPromiseResolve(return_value, return_value->position());
......@@ -4212,8 +4216,8 @@ void ParserTraits::ParseArrowFunctionFormalParameterList(
Scanner::Location* duplicate_loc, bool* ok) {
if (expr->IsEmptyParentheses()) return;
ParseArrowFunctionFormalParameters(parameters, expr, params_loc.end_pos, ok);
if (!*ok) return;
ParseArrowFunctionFormalParameters(parameters, expr, params_loc.end_pos,
CHECK_OK_CUSTOM(Void));
if (parameters->Arity() > Code::kMaxArguments) {
ReportMessageAt(params_loc, MessageTemplate::kMalformedArrowFunParamList);
......@@ -4537,10 +4541,7 @@ void Parser::SkipLazyFunctionBody(int* materialized_literal_count,
scanner()->SeekForward(entry.end_pos() - 1);
scope_->set_end_position(entry.end_pos());
Expect(Token::RBRACE, ok);
if (!*ok) {
return;
}
Expect(Token::RBRACE, CHECK_OK_CUSTOM(Void));
total_preparse_skipped_ += scope_->end_position() - function_block_pos;
*materialized_literal_count = entry.literal_count();
*expected_property_count = entry.property_count();
......@@ -4573,10 +4574,7 @@ void Parser::SkipLazyFunctionBody(int* materialized_literal_count,
return;
}
scope_->set_end_position(logger.end());
Expect(Token::RBRACE, ok);
if (!*ok) {
return;
}
Expect(Token::RBRACE, CHECK_OK_CUSTOM(Void));
total_preparse_skipped_ += scope_->end_position() - function_block_pos;
*materialized_literal_count = logger.literals();
*expected_property_count = logger.properties();
......@@ -5865,8 +5863,7 @@ class NonPatternRewriter : public AstExpressionRewriter {
void Parser::RewriteNonPattern(ExpressionClassifier* classifier, bool* ok) {
ValidateExpression(classifier, ok);
if (!*ok) return;
ValidateExpression(classifier, CHECK_OK_CUSTOM(Void));
auto non_patterns_to_rewrite = function_state_->non_patterns_to_rewrite();
int begin = classifier->GetNonPatternBegin();
int end = non_patterns_to_rewrite->length();
......@@ -7067,5 +7064,9 @@ void Parser::Print(AstNode* node) {
}
#endif // DEBUG
#undef CHECK_OK
#undef CHECK_OK_CUSTOM
#undef CHECK_FAILED
} // namespace internal
} // namespace v8
......@@ -475,6 +475,9 @@ class ParserTraits {
const AstRawString* arg,
ParseErrorType error_type = kSyntaxError);
// A dummy function, just useful as an argument to CHECK_OK_CUSTOM.
static void Void() {}
// "null" return type creators.
static const AstRawString* EmptyIdentifier() {
return NULL;
......
......@@ -20,6 +20,27 @@
namespace v8 {
namespace internal {
// ----------------------------------------------------------------------------
// The CHECK_OK macro is a convenient macro to enforce error
// handling for functions that may fail (by returning !*ok).
//
// CAUTION: This macro appends extra statements after a call,
// thus it must never be used where only a single statement
// is correct (e.g. an if statement branch w/o braces)!
#define CHECK_OK ok); \
if (!*ok) return Statement::Default(); \
((void)0
#define DUMMY ) // to make indentation work
#undef DUMMY
// Used in functions where the return type is not ExpressionT.
#define CHECK_OK_CUSTOM(x) ok); \
if (!*ok) return this->x(); \
((void)0
#define DUMMY ) // to make indentation work
#undef DUMMY
void PreParserTraits::ReportMessageAt(Scanner::Location location,
MessageTemplate::Template message,
const char* arg,
......@@ -226,8 +247,7 @@ void PreParser::ParseStatementList(int end_token, bool* ok,
}
bool starts_with_identifier = peek() == Token::IDENTIFIER;
Scanner::Location token_loc = scanner()->peek_location();
Statement statement = ParseStatementListItem(ok);
if (!*ok) return;
Statement statement = ParseStatementListItem(CHECK_OK_CUSTOM(Void));
if (directive_prologue) {
bool use_strict_found = statement.IsUseStrictLiteral();
......@@ -268,12 +288,6 @@ void PreParser::ParseStatementList(int end_token, bool* ok,
}
#define CHECK_OK ok); \
if (!*ok) return Statement::Default(); \
((void)0
#define DUMMY ) // to make indentation work
#undef DUMMY
PreParser::Statement PreParser::ParseStatement(
AllowLabelledFunctionStatement allow_function, bool* ok) {
// Statement ::
......@@ -918,8 +932,7 @@ PreParser::Statement PreParser::ParseForStatement(bool* ok) {
ExpressionClassifier classifier(this);
Expression lhs = ParseExpression(false, &classifier, CHECK_OK);
int lhs_end_pos = scanner()->location().end_pos;
bool is_for_each = CheckInOrOf(&mode, ok);
if (!*ok) return Statement::Default();
bool is_for_each = CheckInOrOf(&mode, CHECK_OK);
bool is_destructuring = is_for_each &&
(lhs->IsArrayLiteral() || lhs->IsObjectLiteral());
......@@ -1078,6 +1091,7 @@ PreParser::Statement PreParser::ParseDebuggerStatement(bool* ok) {
}
// Redefinition of CHECK_OK for parsing expressions.
#undef CHECK_OK
#define CHECK_OK ok); \
if (!*ok) return Expression::Default(); \
......@@ -1301,14 +1315,14 @@ void PreParserTraits::ParseAsyncArrowSingleExpressionBody(
Scope* scope = pre_parser_->scope_;
scope->ForceContextAllocation();
PreParserExpression return_value =
pre_parser_->ParseAssignmentExpression(accept_IN, classifier, ok);
if (!*ok) return;
PreParserExpression return_value = pre_parser_->ParseAssignmentExpression(
accept_IN, classifier, CHECK_OK_CUSTOM(Void));
body->Add(PreParserStatement::ExpressionStatement(return_value), zone());
}
#undef CHECK_OK
#undef CHECK_OK_CUSTOM
} // namespace internal
......
......@@ -759,6 +759,9 @@ class PreParserTraits {
const char* arg = NULL,
ParseErrorType error_type = kSyntaxError);
// A dummy function, just useful as an argument to CHECK_OK_CUSTOM.
static void Void() {}
// "null" return type creators.
static PreParserIdentifier EmptyIdentifier() {
return PreParserIdentifier::Default();
......
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