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

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

Issue 1723313002: [parser] Enforce module-specific identifier restriction (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Relax assertion criteria Created 4 years, 7 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
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/hashmap.h" 10 #include "src/hashmap.h"
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 v8::Extension* extension, AstValueFactory* ast_value_factory, 98 v8::Extension* extension, AstValueFactory* ast_value_factory,
99 ParserRecorder* log, typename Traits::Type::Parser this_object) 99 ParserRecorder* log, typename Traits::Type::Parser this_object)
100 : Traits(this_object), 100 : Traits(this_object),
101 scope_(NULL), 101 scope_(NULL),
102 function_state_(NULL), 102 function_state_(NULL),
103 extension_(extension), 103 extension_(extension),
104 fni_(NULL), 104 fni_(NULL),
105 ast_value_factory_(ast_value_factory), 105 ast_value_factory_(ast_value_factory),
106 log_(log), 106 log_(log),
107 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly. 107 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly.
108 parsing_module_(false),
108 stack_limit_(stack_limit), 109 stack_limit_(stack_limit),
109 zone_(zone), 110 zone_(zone),
110 scanner_(scanner), 111 scanner_(scanner),
111 stack_overflow_(false), 112 stack_overflow_(false),
112 allow_lazy_(false), 113 allow_lazy_(false),
113 allow_natives_(false), 114 allow_natives_(false),
114 allow_tailcalls_(false), 115 allow_tailcalls_(false),
115 allow_harmony_restrictive_declarations_(false), 116 allow_harmony_restrictive_declarations_(false),
116 allow_harmony_do_expressions_(false), 117 allow_harmony_do_expressions_(false),
117 allow_harmony_for_in_(false), 118 allow_harmony_for_in_(false),
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after
512 if (scanner()->HasAnyLineTerminatorBeforeNext() || 513 if (scanner()->HasAnyLineTerminatorBeforeNext() ||
513 tok == Token::RBRACE || 514 tok == Token::RBRACE ||
514 tok == Token::EOS) { 515 tok == Token::EOS) {
515 return; 516 return;
516 } 517 }
517 Expect(Token::SEMICOLON, ok); 518 Expect(Token::SEMICOLON, ok);
518 } 519 }
519 520
520 bool peek_any_identifier() { 521 bool peek_any_identifier() {
521 Token::Value next = peek(); 522 Token::Value next = peek();
522 return next == Token::IDENTIFIER || next == Token::FUTURE_RESERVED_WORD || 523 return next == Token::IDENTIFIER || next == Token::AWAIT ||
523 next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET || 524 next == Token::ENUM || next == Token::FUTURE_STRICT_RESERVED_WORD ||
524 next == Token::STATIC || next == Token::YIELD; 525 next == Token::LET || next == Token::STATIC || next == Token::YIELD;
525 } 526 }
526 527
527 bool CheckContextualKeyword(Vector<const char> keyword) { 528 bool CheckContextualKeyword(Vector<const char> keyword) {
528 if (PeekContextualKeyword(keyword)) { 529 if (PeekContextualKeyword(keyword)) {
529 Consume(Token::IDENTIFIER); 530 Consume(Token::IDENTIFIER);
530 return true; 531 return true;
531 } 532 }
532 return false; 533 return false;
533 } 534 }
534 535
(...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after
976 bool has_seen_constructor_; 977 bool has_seen_constructor_;
977 }; 978 };
978 979
979 Scope* scope_; // Scope stack. 980 Scope* scope_; // Scope stack.
980 FunctionState* function_state_; // Function state stack. 981 FunctionState* function_state_; // Function state stack.
981 v8::Extension* extension_; 982 v8::Extension* extension_;
982 FuncNameInferrer* fni_; 983 FuncNameInferrer* fni_;
983 AstValueFactory* ast_value_factory_; // Not owned. 984 AstValueFactory* ast_value_factory_; // Not owned.
984 ParserRecorder* log_; 985 ParserRecorder* log_;
985 Mode mode_; 986 Mode mode_;
987 bool parsing_module_;
986 uintptr_t stack_limit_; 988 uintptr_t stack_limit_;
987 989
988 private: 990 private:
989 Zone* zone_; 991 Zone* zone_;
990 992
991 Scanner* scanner_; 993 Scanner* scanner_;
992 bool stack_overflow_; 994 bool stack_overflow_;
993 995
994 bool allow_lazy_; 996 bool allow_lazy_;
995 bool allow_natives_; 997 bool allow_natives_;
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1050 case Token::SMI: 1052 case Token::SMI:
1051 case Token::NUMBER: 1053 case Token::NUMBER:
1052 *message = MessageTemplate::kUnexpectedTokenNumber; 1054 *message = MessageTemplate::kUnexpectedTokenNumber;
1053 break; 1055 break;
1054 case Token::STRING: 1056 case Token::STRING:
1055 *message = MessageTemplate::kUnexpectedTokenString; 1057 *message = MessageTemplate::kUnexpectedTokenString;
1056 break; 1058 break;
1057 case Token::IDENTIFIER: 1059 case Token::IDENTIFIER:
1058 *message = MessageTemplate::kUnexpectedTokenIdentifier; 1060 *message = MessageTemplate::kUnexpectedTokenIdentifier;
1059 break; 1061 break;
1060 case Token::FUTURE_RESERVED_WORD: 1062 case Token::AWAIT:
1063 case Token::ENUM:
1061 *message = MessageTemplate::kUnexpectedReserved; 1064 *message = MessageTemplate::kUnexpectedReserved;
1062 break; 1065 break;
1063 case Token::LET: 1066 case Token::LET:
1064 case Token::STATIC: 1067 case Token::STATIC:
1065 case Token::YIELD: 1068 case Token::YIELD:
1066 case Token::FUTURE_STRICT_RESERVED_WORD: 1069 case Token::FUTURE_STRICT_RESERVED_WORD:
1067 *message = is_strict(language_mode()) 1070 *message = is_strict(language_mode())
1068 ? MessageTemplate::kUnexpectedStrictReserved 1071 ? MessageTemplate::kUnexpectedStrictReserved
1069 : MessageTemplate::kUnexpectedTokenIdentifier; 1072 : MessageTemplate::kUnexpectedTokenIdentifier;
1070 break; 1073 break;
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1125 1128
1126 return result; 1129 return result;
1127 } 1130 }
1128 1131
1129 1132
1130 template <class Traits> 1133 template <class Traits>
1131 typename ParserBase<Traits>::IdentifierT 1134 typename ParserBase<Traits>::IdentifierT
1132 ParserBase<Traits>::ParseAndClassifyIdentifier(ExpressionClassifier* classifier, 1135 ParserBase<Traits>::ParseAndClassifyIdentifier(ExpressionClassifier* classifier,
1133 bool* ok) { 1136 bool* ok) {
1134 Token::Value next = Next(); 1137 Token::Value next = Next();
1135 if (next == Token::IDENTIFIER) { 1138 if (next == Token::IDENTIFIER || (next == Token::AWAIT && !parsing_module_)) {
1136 IdentifierT name = this->GetSymbol(scanner()); 1139 IdentifierT name = this->GetSymbol(scanner());
1137 // When this function is used to read a formal parameter, we don't always 1140 // When this function is used to read a formal parameter, we don't always
1138 // know whether the function is going to be strict or sloppy. Indeed for 1141 // know whether the function is going to be strict or sloppy. Indeed for
1139 // arrow functions we don't always know that the identifier we are reading 1142 // arrow functions we don't always know that the identifier we are reading
1140 // is actually a formal parameter. Therefore besides the errors that we 1143 // is actually a formal parameter. Therefore besides the errors that we
1141 // must detect because we know we're in strict mode, we also record any 1144 // must detect because we know we're in strict mode, we also record any
1142 // error that we might make in the future once we know the language mode. 1145 // error that we might make in the future once we know the language mode.
1143 if (this->IsEval(name)) { 1146 if (this->IsEval(name)) {
1144 classifier->RecordStrictModeFormalParameterError( 1147 classifier->RecordStrictModeFormalParameterError(
1145 scanner()->location(), MessageTemplate::kStrictEvalArguments); 1148 scanner()->location(), MessageTemplate::kStrictEvalArguments);
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1189 return Traits::EmptyIdentifier(); 1192 return Traits::EmptyIdentifier();
1190 } 1193 }
1191 } 1194 }
1192 1195
1193 1196
1194 template <class Traits> 1197 template <class Traits>
1195 typename ParserBase<Traits>::IdentifierT 1198 typename ParserBase<Traits>::IdentifierT
1196 ParserBase<Traits>::ParseIdentifierOrStrictReservedWord( 1199 ParserBase<Traits>::ParseIdentifierOrStrictReservedWord(
1197 bool is_generator, bool* is_strict_reserved, bool* ok) { 1200 bool is_generator, bool* is_strict_reserved, bool* ok) {
1198 Token::Value next = Next(); 1201 Token::Value next = Next();
1199 if (next == Token::IDENTIFIER) { 1202 if (next == Token::IDENTIFIER || (next == Token::AWAIT && !parsing_module_)) {
1200 *is_strict_reserved = false; 1203 *is_strict_reserved = false;
1201 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET || 1204 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET ||
1202 next == Token::STATIC || (next == Token::YIELD && !is_generator)) { 1205 next == Token::STATIC || (next == Token::YIELD && !is_generator)) {
1203 *is_strict_reserved = true; 1206 *is_strict_reserved = true;
1204 } else { 1207 } else {
1205 ReportUnexpectedToken(next); 1208 ReportUnexpectedToken(next);
1206 *ok = false; 1209 *ok = false;
1207 return Traits::EmptyIdentifier(); 1210 return Traits::EmptyIdentifier();
1208 } 1211 }
1209 1212
1210 IdentifierT name = this->GetSymbol(scanner()); 1213 IdentifierT name = this->GetSymbol(scanner());
1211 if (this->IsArguments(name)) scope_->RecordArgumentsUsage(); 1214 if (this->IsArguments(name)) scope_->RecordArgumentsUsage();
1212 return name; 1215 return name;
1213 } 1216 }
1214 1217
1215
1216 template <class Traits> 1218 template <class Traits>
1217 typename ParserBase<Traits>::IdentifierT 1219 typename ParserBase<Traits>::IdentifierT
1218 ParserBase<Traits>::ParseIdentifierName(bool* ok) { 1220 ParserBase<Traits>::ParseIdentifierName(bool* ok) {
1219 Token::Value next = Next(); 1221 Token::Value next = Next();
1220 if (next != Token::IDENTIFIER && next != Token::FUTURE_RESERVED_WORD && 1222 if (next != Token::IDENTIFIER && next != Token::ENUM &&
1221 next != Token::LET && next != Token::STATIC && next != Token::YIELD && 1223 next != Token::AWAIT && next != Token::LET && next != Token::STATIC &&
1222 next != Token::FUTURE_STRICT_RESERVED_WORD && 1224 next != Token::YIELD && next != Token::FUTURE_STRICT_RESERVED_WORD &&
1223 next != Token::ESCAPED_KEYWORD && 1225 next != Token::ESCAPED_KEYWORD &&
1224 next != Token::ESCAPED_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) { 1226 next != Token::ESCAPED_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) {
1225 this->ReportUnexpectedToken(next); 1227 this->ReportUnexpectedToken(next);
1226 *ok = false; 1228 *ok = false;
1227 return Traits::EmptyIdentifier(); 1229 return Traits::EmptyIdentifier();
1228 } 1230 }
1229 1231
1230 IdentifierT name = this->GetSymbol(scanner()); 1232 IdentifierT name = this->GetSymbol(scanner());
1231 if (this->IsArguments(name)) scope_->RecordArgumentsUsage(); 1233 if (this->IsArguments(name)) scope_->RecordArgumentsUsage();
1232 return name; 1234 return name;
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
1309 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory()); 1311 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory());
1310 case Token::SMI: 1312 case Token::SMI:
1311 case Token::NUMBER: 1313 case Token::NUMBER:
1312 BindingPatternUnexpectedToken(classifier); 1314 BindingPatternUnexpectedToken(classifier);
1313 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory()); 1315 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory());
1314 1316
1315 case Token::IDENTIFIER: 1317 case Token::IDENTIFIER:
1316 case Token::LET: 1318 case Token::LET:
1317 case Token::STATIC: 1319 case Token::STATIC:
1318 case Token::YIELD: 1320 case Token::YIELD:
1321 case Token::AWAIT:
1319 case Token::ESCAPED_STRICT_RESERVED_WORD: 1322 case Token::ESCAPED_STRICT_RESERVED_WORD:
1320 case Token::FUTURE_STRICT_RESERVED_WORD: { 1323 case Token::FUTURE_STRICT_RESERVED_WORD: {
1321 // Using eval or arguments in this context is OK even in strict mode. 1324 // Using eval or arguments in this context is OK even in strict mode.
1322 IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK); 1325 IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK);
1323 return this->ExpressionFromIdentifier( 1326 return this->ExpressionFromIdentifier(
1324 name, beg_pos, scanner()->location().end_pos, scope_, factory()); 1327 name, beg_pos, scanner()->location().end_pos, scope_, factory());
1325 } 1328 }
1326 1329
1327 case Token::STRING: { 1330 case Token::STRING: {
1328 BindingPatternUnexpectedToken(classifier); 1331 BindingPatternUnexpectedToken(classifier);
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after
1676 int beg_pos = peek_position(); 1679 int beg_pos = peek_position();
1677 value = this->ParseAssignmentExpression( 1680 value = this->ParseAssignmentExpression(
1678 true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 1681 true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
1679 CheckDestructuringElement(value, classifier, beg_pos, 1682 CheckDestructuringElement(value, classifier, beg_pos,
1680 scanner()->location().end_pos); 1683 scanner()->location().end_pos);
1681 1684
1682 return factory()->NewObjectLiteralProperty(name_expression, value, false, 1685 return factory()->NewObjectLiteralProperty(name_expression, value, false,
1683 *is_computed_name); 1686 *is_computed_name);
1684 } 1687 }
1685 1688
1686 if (Token::IsIdentifier(name_token, language_mode(), 1689 if (Token::IsIdentifier(name_token, language_mode(), this->is_generator(),
1687 this->is_generator()) && 1690 parsing_module_) &&
1688 (peek() == Token::COMMA || peek() == Token::RBRACE || 1691 (peek() == Token::COMMA || peek() == Token::RBRACE ||
1689 peek() == Token::ASSIGN)) { 1692 peek() == Token::ASSIGN)) {
1690 // PropertyDefinition 1693 // PropertyDefinition
1691 // IdentifierReference 1694 // IdentifierReference
1692 // CoverInitializedName 1695 // CoverInitializedName
1693 // 1696 //
1694 // CoverInitializedName 1697 // CoverInitializedName
1695 // IdentifierReference Initializer? 1698 // IdentifierReference Initializer?
1696 if (classifier->duplicate_finder() != nullptr && 1699 if (classifier->duplicate_finder() != nullptr &&
1697 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) { 1700 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) {
(...skipping 1161 matching lines...) Expand 10 before | Expand all | Expand 10 after
2859 bool ParserBase<Traits>::IsNextLetKeyword() { 2862 bool ParserBase<Traits>::IsNextLetKeyword() {
2860 DCHECK(peek() == Token::LET); 2863 DCHECK(peek() == Token::LET);
2861 Token::Value next_next = PeekAhead(); 2864 Token::Value next_next = PeekAhead();
2862 switch (next_next) { 2865 switch (next_next) {
2863 case Token::LBRACE: 2866 case Token::LBRACE:
2864 case Token::LBRACK: 2867 case Token::LBRACK:
2865 case Token::IDENTIFIER: 2868 case Token::IDENTIFIER:
2866 case Token::STATIC: 2869 case Token::STATIC:
2867 case Token::LET: // Yes, you can do let let = ... in sloppy mode 2870 case Token::LET: // Yes, you can do let let = ... in sloppy mode
2868 case Token::YIELD: 2871 case Token::YIELD:
2872 case Token::AWAIT:
2869 return true; 2873 return true;
2870 default: 2874 default:
2871 return false; 2875 return false;
2872 } 2876 }
2873 } 2877 }
2874 2878
2875 2879
2876 template <class Traits> 2880 template <class Traits>
2877 typename ParserBase<Traits>::ExpressionT 2881 typename ParserBase<Traits>::ExpressionT
2878 ParserBase<Traits>::ParseArrowFunctionLiteral( 2882 ParserBase<Traits>::ParseArrowFunctionLiteral(
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after
3207 has_seen_constructor_ = true; 3211 has_seen_constructor_ = true;
3208 return; 3212 return;
3209 } 3213 }
3210 } 3214 }
3211 3215
3212 3216
3213 } // namespace internal 3217 } // namespace internal
3214 } // namespace v8 3218 } // namespace v8
3215 3219
3216 #endif // V8_PARSING_PARSER_BASE_H 3220 #endif // V8_PARSING_PARSER_BASE_H
OLDNEW
« no previous file with comments | « src/parsing/parser.cc ('k') | src/parsing/preparser.h » ('j') | test/cctest/test-parsing.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698