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

Side by Side Diff: src/parsing/parser-base.h

Issue 2154253002: [parser] Refactor some CHECK_OK calls (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 5 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 unified diff | Download patch
« no previous file with comments | « src/parsing/parser.cc ('k') | src/parsing/preparser.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef V8_PARSING_PARSER_BASE_H 5 #ifndef V8_PARSING_PARSER_BASE_H
6 #define V8_PARSING_PARSER_BASE_H 6 #define V8_PARSING_PARSER_BASE_H
7 7
8 #include "src/ast/scopes.h" 8 #include "src/ast/scopes.h"
9 #include "src/bailout-reason.h" 9 #include "src/bailout-reason.h"
10 #include "src/base/hashmap.h" 10 #include "src/base/hashmap.h"
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
112 112
113 struct FormalParametersBase { 113 struct FormalParametersBase {
114 explicit FormalParametersBase(Scope* scope) : scope(scope) {} 114 explicit FormalParametersBase(Scope* scope) : scope(scope) {}
115 Scope* scope; 115 Scope* scope;
116 bool has_rest = false; 116 bool has_rest = false;
117 bool is_simple = true; 117 bool is_simple = true;
118 int materialized_literals_count = 0; 118 int materialized_literals_count = 0;
119 }; 119 };
120 120
121 121
122 // ----------------------------------------------------------------------------
123 // The CHECK_OK macro is a convenient macro to enforce error
124 // handling for functions that may fail (by returning !*ok).
125 //
126 // CAUTION: This macro appends extra statements after a call,
127 // thus it must never be used where only a single statement
128 // is correct (e.g. an if statement branch w/o braces)!
129
130 #define CHECK_OK ok); \
131 if (!*ok) return this->EmptyExpression(); \
132 ((void)0
133 #define DUMMY ) // to make indentation work
134 #undef DUMMY
135
136 // Used in functions where the return type is not ExpressionT.
137 #define CHECK_OK_CUSTOM(x) ok); \
138 if (!*ok) return this->x(); \
139 ((void)0
140 #define DUMMY ) // to make indentation work
141 #undef DUMMY
142
143
122 // Common base class shared between parser and pre-parser. Traits encapsulate 144 // Common base class shared between parser and pre-parser. Traits encapsulate
123 // the differences between Parser and PreParser: 145 // the differences between Parser and PreParser:
124 146
125 // - Return types: For example, Parser functions return Expression* and 147 // - Return types: For example, Parser functions return Expression* and
126 // PreParser functions return PreParserExpression. 148 // PreParser functions return PreParserExpression.
127 149
128 // - Creating parse tree nodes: Parser generates an AST during the recursive 150 // - Creating parse tree nodes: Parser generates an AST during the recursive
129 // descent. PreParser doesn't create a tree. Instead, it passes around minimal 151 // descent. PreParser doesn't create a tree. Instead, it passes around minimal
130 // data objects (PreParserExpression, PreParserIdentifier etc.) which contain 152 // data objects (PreParserExpression, PreParserIdentifier etc.) which contain
131 // just enough data for the upper layer functions. PreParserFactory is 153 // just enough data for the upper layer functions. PreParserFactory is
(...skipping 531 matching lines...) Expand 10 before | Expand all | Expand 10 after
663 return; 685 return;
664 } 686 }
665 if (scanner()->HasAnyLineTerminatorBeforeNext() || 687 if (scanner()->HasAnyLineTerminatorBeforeNext() ||
666 tok == Token::RBRACE || 688 tok == Token::RBRACE ||
667 tok == Token::EOS) { 689 tok == Token::EOS) {
668 return; 690 return;
669 } 691 }
670 Expect(Token::SEMICOLON, ok); 692 Expect(Token::SEMICOLON, ok);
671 } 693 }
672 694
695 // A dummy function, just useful as an argument to CHECK_OK_CUSTOM.
696 static void Void() {}
697
673 bool is_any_identifier(Token::Value token) { 698 bool is_any_identifier(Token::Value token) {
674 return token == Token::IDENTIFIER || token == Token::ENUM || 699 return token == Token::IDENTIFIER || token == Token::ENUM ||
675 token == Token::AWAIT || token == Token::ASYNC || 700 token == Token::AWAIT || token == Token::ASYNC ||
676 token == Token::FUTURE_STRICT_RESERVED_WORD || token == Token::LET || 701 token == Token::FUTURE_STRICT_RESERVED_WORD || token == Token::LET ||
677 token == Token::STATIC || token == Token::YIELD; 702 token == Token::STATIC || token == Token::YIELD;
678 } 703 }
679 bool peek_any_identifier() { return is_any_identifier(peek()); } 704 bool peek_any_identifier() { return is_any_identifier(peek()); }
680 705
681 bool CheckContextualKeyword(Vector<const char> keyword) { 706 bool CheckContextualKeyword(Vector<const char> keyword) {
682 if (PeekContextualKeyword(keyword)) { 707 if (PeekContextualKeyword(keyword)) {
683 Consume(Token::IDENTIFIER); 708 Consume(Token::IDENTIFIER);
684 return true; 709 return true;
685 } 710 }
686 return false; 711 return false;
687 } 712 }
688 713
689 bool PeekContextualKeyword(Vector<const char> keyword) { 714 bool PeekContextualKeyword(Vector<const char> keyword) {
690 return peek() == Token::IDENTIFIER && 715 return peek() == Token::IDENTIFIER &&
691 scanner()->is_next_contextual_keyword(keyword); 716 scanner()->is_next_contextual_keyword(keyword);
692 } 717 }
693 718
694 void ExpectMetaProperty(Vector<const char> property_name, 719 void ExpectMetaProperty(Vector<const char> property_name,
695 const char* full_name, int pos, bool* ok); 720 const char* full_name, int pos, bool* ok);
696 721
697 void ExpectContextualKeyword(Vector<const char> keyword, bool* ok) { 722 void ExpectContextualKeyword(Vector<const char> keyword, bool* ok) {
698 Expect(Token::IDENTIFIER, ok); 723 Expect(Token::IDENTIFIER, CHECK_OK_CUSTOM(Void));
699 if (!*ok) return;
700 if (!scanner()->is_literal_contextual_keyword(keyword)) { 724 if (!scanner()->is_literal_contextual_keyword(keyword)) {
701 ReportUnexpectedToken(scanner()->current_token()); 725 ReportUnexpectedToken(scanner()->current_token());
702 *ok = false; 726 *ok = false;
703 } 727 }
704 } 728 }
705 729
706 bool CheckInOrOf(ForEachStatement::VisitMode* visit_mode, bool* ok) { 730 bool CheckInOrOf(ForEachStatement::VisitMode* visit_mode, bool* ok) {
707 if (Check(Token::IN)) { 731 if (Check(Token::IN)) {
708 *visit_mode = ForEachStatement::ENUMERATE; 732 *visit_mode = ForEachStatement::ENUMERATE;
709 return true; 733 return true;
(...skipping 594 matching lines...) Expand 10 before | Expand all | Expand 10 after
1304 const char* arg; 1328 const char* arg;
1305 GetUnexpectedTokenMessage(token, &message, &source_location, &arg); 1329 GetUnexpectedTokenMessage(token, &message, &source_location, &arg);
1306 Traits::ReportMessageAt(source_location, message, arg); 1330 Traits::ReportMessageAt(source_location, message, arg);
1307 } 1331 }
1308 1332
1309 1333
1310 template <class Traits> 1334 template <class Traits>
1311 typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier( 1335 typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier(
1312 AllowRestrictedIdentifiers allow_restricted_identifiers, bool* ok) { 1336 AllowRestrictedIdentifiers allow_restricted_identifiers, bool* ok) {
1313 ExpressionClassifier classifier(this); 1337 ExpressionClassifier classifier(this);
1314 auto result = ParseAndClassifyIdentifier(&classifier, ok); 1338 auto result =
1315 if (!*ok) return Traits::EmptyIdentifier(); 1339 ParseAndClassifyIdentifier(&classifier, CHECK_OK_CUSTOM(EmptyIdentifier));
1316 1340
1317 if (allow_restricted_identifiers == kDontAllowRestrictedIdentifiers) { 1341 if (allow_restricted_identifiers == kDontAllowRestrictedIdentifiers) {
1318 ValidateAssignmentPattern(&classifier, ok); 1342 ValidateAssignmentPattern(&classifier, CHECK_OK_CUSTOM(EmptyIdentifier));
1319 if (!*ok) return Traits::EmptyIdentifier(); 1343 ValidateBindingPattern(&classifier, CHECK_OK_CUSTOM(EmptyIdentifier));
1320 ValidateBindingPattern(&classifier, ok);
1321 if (!*ok) return Traits::EmptyIdentifier();
1322 } 1344 }
1323 1345
1324 return result; 1346 return result;
1325 } 1347 }
1326 1348
1327 1349
1328 template <class Traits> 1350 template <class Traits>
1329 typename ParserBase<Traits>::IdentifierT 1351 typename ParserBase<Traits>::IdentifierT
1330 ParserBase<Traits>::ParseAndClassifyIdentifier(ExpressionClassifier* classifier, 1352 ParserBase<Traits>::ParseAndClassifyIdentifier(ExpressionClassifier* classifier,
1331 bool* ok) { 1353 bool* ok) {
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
1461 ReportMessage(MessageTemplate::kMalformedRegExpFlags); 1483 ReportMessage(MessageTemplate::kMalformedRegExpFlags);
1462 *ok = false; 1484 *ok = false;
1463 return Traits::EmptyExpression(); 1485 return Traits::EmptyExpression();
1464 } 1486 }
1465 int js_flags = flags.FromJust(); 1487 int js_flags = flags.FromJust();
1466 Next(); 1488 Next();
1467 return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos); 1489 return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos);
1468 } 1490 }
1469 1491
1470 1492
1471 #define CHECK_OK ok); \
1472 if (!*ok) return this->EmptyExpression(); \
1473 ((void)0
1474 #define DUMMY ) // to make indentation work
1475 #undef DUMMY
1476
1477 // Used in functions where the return type is not ExpressionT.
1478 #define CHECK_OK_CUSTOM(x) ok); \
1479 if (!*ok) return this->x(); \
1480 ((void)0
1481 #define DUMMY ) // to make indentation work
1482 #undef DUMMY
1483
1484 template <class Traits> 1493 template <class Traits>
1485 typename ParserBase<Traits>::ExpressionT 1494 typename ParserBase<Traits>::ExpressionT
1486 ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier, 1495 ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
1487 bool* is_async, bool* ok) { 1496 bool* is_async, bool* ok) {
1488 // PrimaryExpression :: 1497 // PrimaryExpression ::
1489 // 'this' 1498 // 'this'
1490 // 'null' 1499 // 'null'
1491 // 'true' 1500 // 'true'
1492 // 'false' 1501 // 'false'
1493 // Identifier 1502 // Identifier
(...skipping 1583 matching lines...) Expand 10 before | Expand all | Expand 10 after
3077 ReportMessageAt(scanner()->location(), MessageTemplate::kUnexpectedSuper); 3086 ReportMessageAt(scanner()->location(), MessageTemplate::kUnexpectedSuper);
3078 *ok = false; 3087 *ok = false;
3079 return this->EmptyExpression(); 3088 return this->EmptyExpression();
3080 } 3089 }
3081 3090
3082 template <class Traits> 3091 template <class Traits>
3083 void ParserBase<Traits>::ExpectMetaProperty(Vector<const char> property_name, 3092 void ParserBase<Traits>::ExpectMetaProperty(Vector<const char> property_name,
3084 const char* full_name, int pos, 3093 const char* full_name, int pos,
3085 bool* ok) { 3094 bool* ok) {
3086 Consume(Token::PERIOD); 3095 Consume(Token::PERIOD);
3087 ExpectContextualKeyword(property_name, ok); 3096 ExpectContextualKeyword(property_name, CHECK_OK_CUSTOM(Void));
3088 if (!*ok) return;
3089 if (scanner()->literal_contains_escapes()) { 3097 if (scanner()->literal_contains_escapes()) {
3090 Traits::ReportMessageAt( 3098 Traits::ReportMessageAt(
3091 Scanner::Location(pos, scanner()->location().end_pos), 3099 Scanner::Location(pos, scanner()->location().end_pos),
3092 MessageTemplate::kInvalidEscapedMetaProperty, full_name); 3100 MessageTemplate::kInvalidEscapedMetaProperty, full_name);
3093 *ok = false; 3101 *ok = false;
3094 } 3102 }
3095 } 3103 }
3096 3104
3097 template <class Traits> 3105 template <class Traits>
3098 typename ParserBase<Traits>::ExpressionT 3106 typename ParserBase<Traits>::ExpressionT
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
3187 } 3195 }
3188 3196
3189 3197
3190 template <class Traits> 3198 template <class Traits>
3191 void ParserBase<Traits>::ParseFormalParameter( 3199 void ParserBase<Traits>::ParseFormalParameter(
3192 FormalParametersT* parameters, ExpressionClassifier* classifier, bool* ok) { 3200 FormalParametersT* parameters, ExpressionClassifier* classifier, bool* ok) {
3193 // FormalParameter[Yield,GeneratorParameter] : 3201 // FormalParameter[Yield,GeneratorParameter] :
3194 // BindingElement[?Yield, ?GeneratorParameter] 3202 // BindingElement[?Yield, ?GeneratorParameter]
3195 bool is_rest = parameters->has_rest; 3203 bool is_rest = parameters->has_rest;
3196 3204
3197 ExpressionT pattern = ParsePrimaryExpression(classifier, ok); 3205 ExpressionT pattern =
3198 if (!*ok) return; 3206 ParsePrimaryExpression(classifier, CHECK_OK_CUSTOM(Void));
3199 3207 ValidateBindingPattern(classifier, CHECK_OK_CUSTOM(Void));
3200 ValidateBindingPattern(classifier, ok);
3201 if (!*ok) return;
3202 3208
3203 if (!Traits::IsIdentifier(pattern)) { 3209 if (!Traits::IsIdentifier(pattern)) {
3204 parameters->is_simple = false; 3210 parameters->is_simple = false;
3205 ValidateFormalParameterInitializer(classifier, ok); 3211 ValidateFormalParameterInitializer(classifier, CHECK_OK_CUSTOM(Void));
3206 if (!*ok) return;
3207 classifier->RecordNonSimpleParameter(); 3212 classifier->RecordNonSimpleParameter();
3208 } 3213 }
3209 3214
3210 ExpressionT initializer = Traits::EmptyExpression(); 3215 ExpressionT initializer = Traits::EmptyExpression();
3211 if (!is_rest && Check(Token::ASSIGN)) { 3216 if (!is_rest && Check(Token::ASSIGN)) {
3212 ExpressionClassifier init_classifier(this); 3217 ExpressionClassifier init_classifier(this);
3213 initializer = ParseAssignmentExpression(true, &init_classifier, ok); 3218 initializer = ParseAssignmentExpression(true, &init_classifier,
3214 if (!*ok) return; 3219 CHECK_OK_CUSTOM(Void));
3215 Traits::RewriteNonPattern(&init_classifier, ok); 3220 Traits::RewriteNonPattern(&init_classifier, CHECK_OK_CUSTOM(Void));
3216 ValidateFormalParameterInitializer(&init_classifier, ok); 3221 ValidateFormalParameterInitializer(&init_classifier, CHECK_OK_CUSTOM(Void));
3217 if (!*ok) return;
3218 parameters->is_simple = false; 3222 parameters->is_simple = false;
3219 init_classifier.Discard(); 3223 init_classifier.Discard();
3220 classifier->RecordNonSimpleParameter(); 3224 classifier->RecordNonSimpleParameter();
3221 3225
3222 Traits::SetFunctionNameFromIdentifierRef(initializer, pattern); 3226 Traits::SetFunctionNameFromIdentifierRef(initializer, pattern);
3223 } 3227 }
3224 3228
3225 Traits::AddFormalParameter(parameters, pattern, initializer, 3229 Traits::AddFormalParameter(parameters, pattern, initializer,
3226 scanner()->location().end_pos, is_rest); 3230 scanner()->location().end_pos, is_rest);
3227 } 3231 }
(...skipping 16 matching lines...) Expand all
3244 DCHECK_EQ(0, parameters->Arity()); 3248 DCHECK_EQ(0, parameters->Arity());
3245 3249
3246 if (peek() != Token::RPAREN) { 3250 if (peek() != Token::RPAREN) {
3247 while (true) { 3251 while (true) {
3248 if (parameters->Arity() > Code::kMaxArguments) { 3252 if (parameters->Arity() > Code::kMaxArguments) {
3249 ReportMessage(MessageTemplate::kTooManyParameters); 3253 ReportMessage(MessageTemplate::kTooManyParameters);
3250 *ok = false; 3254 *ok = false;
3251 return; 3255 return;
3252 } 3256 }
3253 parameters->has_rest = Check(Token::ELLIPSIS); 3257 parameters->has_rest = Check(Token::ELLIPSIS);
3254 ParseFormalParameter(parameters, classifier, ok); 3258 ParseFormalParameter(parameters, classifier, CHECK_OK_CUSTOM(Void));
3255 if (!*ok) return;
3256 3259
3257 if (parameters->has_rest) { 3260 if (parameters->has_rest) {
3258 parameters->is_simple = false; 3261 parameters->is_simple = false;
3259 classifier->RecordNonSimpleParameter(); 3262 classifier->RecordNonSimpleParameter();
3260 if (peek() == Token::COMMA) { 3263 if (peek() == Token::COMMA) {
3261 ReportMessageAt(scanner()->peek_location(), 3264 ReportMessageAt(scanner()->peek_location(),
3262 MessageTemplate::kParamAfterRest); 3265 MessageTemplate::kParamAfterRest);
3263 *ok = false; 3266 *ok = false;
3264 return; 3267 return;
3265 } 3268 }
(...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after
3665 has_seen_constructor_ = true; 3668 has_seen_constructor_ = true;
3666 return; 3669 return;
3667 } 3670 }
3668 } 3671 }
3669 3672
3670 3673
3671 } // namespace internal 3674 } // namespace internal
3672 } // namespace v8 3675 } // namespace v8
3673 3676
3674 #endif // V8_PARSING_PARSER_BASE_H 3677 #endif // V8_PARSING_PARSER_BASE_H
OLDNEW
« no previous file with comments | « src/parsing/parser.cc ('k') | src/parsing/preparser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698