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

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: Incorporate latest review feedback Created 4 years, 8 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/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 stack_limit_(stack_limit), 108 stack_limit_(stack_limit),
adamk 2016/04/22 23:11:00 Please initialize parsing_module_ to false here.
mike3 2016/04/22 23:30:33 Acknowledged.
109 zone_(zone), 109 zone_(zone),
110 scanner_(scanner), 110 scanner_(scanner),
111 stack_overflow_(false), 111 stack_overflow_(false),
112 allow_lazy_(false), 112 allow_lazy_(false),
113 allow_natives_(false), 113 allow_natives_(false),
114 allow_tailcalls_(false), 114 allow_tailcalls_(false),
115 allow_harmony_restrictive_declarations_(false), 115 allow_harmony_restrictive_declarations_(false),
116 allow_harmony_do_expressions_(false), 116 allow_harmony_do_expressions_(false),
117 allow_harmony_function_name_(false), 117 allow_harmony_function_name_(false),
118 allow_harmony_function_sent_(false) {} 118 allow_harmony_function_sent_(false) {}
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after
457 if (scanner()->HasAnyLineTerminatorBeforeNext() || 457 if (scanner()->HasAnyLineTerminatorBeforeNext() ||
458 tok == Token::RBRACE || 458 tok == Token::RBRACE ||
459 tok == Token::EOS) { 459 tok == Token::EOS) {
460 return; 460 return;
461 } 461 }
462 Expect(Token::SEMICOLON, ok); 462 Expect(Token::SEMICOLON, ok);
463 } 463 }
464 464
465 bool peek_any_identifier() { 465 bool peek_any_identifier() {
466 Token::Value next = peek(); 466 Token::Value next = peek();
467 return next == Token::IDENTIFIER || next == Token::FUTURE_RESERVED_WORD || 467 return next == Token::IDENTIFIER || next == Token::AWAIT ||
468 next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET || 468 next == Token::ENUM || next == Token::FUTURE_STRICT_RESERVED_WORD ||
469 next == Token::STATIC || next == Token::YIELD; 469 next == Token::LET || next == Token::STATIC || next == Token::YIELD;
470 } 470 }
471 471
472 bool CheckContextualKeyword(Vector<const char> keyword) { 472 bool CheckContextualKeyword(Vector<const char> keyword) {
473 if (PeekContextualKeyword(keyword)) { 473 if (PeekContextualKeyword(keyword)) {
474 Consume(Token::IDENTIFIER); 474 Consume(Token::IDENTIFIER);
475 return true; 475 return true;
476 } 476 }
477 return false; 477 return false;
478 } 478 }
479 479
(...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after
903 bool has_seen_constructor_; 903 bool has_seen_constructor_;
904 }; 904 };
905 905
906 Scope* scope_; // Scope stack. 906 Scope* scope_; // Scope stack.
907 FunctionState* function_state_; // Function state stack. 907 FunctionState* function_state_; // Function state stack.
908 v8::Extension* extension_; 908 v8::Extension* extension_;
909 FuncNameInferrer* fni_; 909 FuncNameInferrer* fni_;
910 AstValueFactory* ast_value_factory_; // Not owned. 910 AstValueFactory* ast_value_factory_; // Not owned.
911 ParserRecorder* log_; 911 ParserRecorder* log_;
912 Mode mode_; 912 Mode mode_;
913 bool parsing_module_;
913 uintptr_t stack_limit_; 914 uintptr_t stack_limit_;
914 915
915 private: 916 private:
916 Zone* zone_; 917 Zone* zone_;
917 918
918 Scanner* scanner_; 919 Scanner* scanner_;
919 bool stack_overflow_; 920 bool stack_overflow_;
920 921
921 bool allow_lazy_; 922 bool allow_lazy_;
922 bool allow_natives_; 923 bool allow_natives_;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
976 case Token::SMI: 977 case Token::SMI:
977 case Token::NUMBER: 978 case Token::NUMBER:
978 *message = MessageTemplate::kUnexpectedTokenNumber; 979 *message = MessageTemplate::kUnexpectedTokenNumber;
979 break; 980 break;
980 case Token::STRING: 981 case Token::STRING:
981 *message = MessageTemplate::kUnexpectedTokenString; 982 *message = MessageTemplate::kUnexpectedTokenString;
982 break; 983 break;
983 case Token::IDENTIFIER: 984 case Token::IDENTIFIER:
984 *message = MessageTemplate::kUnexpectedTokenIdentifier; 985 *message = MessageTemplate::kUnexpectedTokenIdentifier;
985 break; 986 break;
986 case Token::FUTURE_RESERVED_WORD: 987 case Token::AWAIT:
988 case Token::ENUM:
987 *message = MessageTemplate::kUnexpectedReserved; 989 *message = MessageTemplate::kUnexpectedReserved;
988 break; 990 break;
989 case Token::LET: 991 case Token::LET:
990 case Token::STATIC: 992 case Token::STATIC:
991 case Token::YIELD: 993 case Token::YIELD:
992 case Token::FUTURE_STRICT_RESERVED_WORD: 994 case Token::FUTURE_STRICT_RESERVED_WORD:
993 *message = is_strict(language_mode()) 995 *message = is_strict(language_mode())
994 ? MessageTemplate::kUnexpectedStrictReserved 996 ? MessageTemplate::kUnexpectedStrictReserved
995 : MessageTemplate::kUnexpectedTokenIdentifier; 997 : MessageTemplate::kUnexpectedTokenIdentifier;
996 break; 998 break;
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1051 1053
1052 return result; 1054 return result;
1053 } 1055 }
1054 1056
1055 1057
1056 template <class Traits> 1058 template <class Traits>
1057 typename ParserBase<Traits>::IdentifierT 1059 typename ParserBase<Traits>::IdentifierT
1058 ParserBase<Traits>::ParseAndClassifyIdentifier(ExpressionClassifier* classifier, 1060 ParserBase<Traits>::ParseAndClassifyIdentifier(ExpressionClassifier* classifier,
1059 bool* ok) { 1061 bool* ok) {
1060 Token::Value next = Next(); 1062 Token::Value next = Next();
1061 if (next == Token::IDENTIFIER) { 1063 if (next == Token::IDENTIFIER || (next == Token::AWAIT && !parsing_module_)) {
1062 IdentifierT name = this->GetSymbol(scanner()); 1064 IdentifierT name = this->GetSymbol(scanner());
1063 // When this function is used to read a formal parameter, we don't always 1065 // When this function is used to read a formal parameter, we don't always
1064 // know whether the function is going to be strict or sloppy. Indeed for 1066 // know whether the function is going to be strict or sloppy. Indeed for
1065 // arrow functions we don't always know that the identifier we are reading 1067 // arrow functions we don't always know that the identifier we are reading
1066 // is actually a formal parameter. Therefore besides the errors that we 1068 // is actually a formal parameter. Therefore besides the errors that we
1067 // must detect because we know we're in strict mode, we also record any 1069 // must detect because we know we're in strict mode, we also record any
1068 // error that we might make in the future once we know the language mode. 1070 // error that we might make in the future once we know the language mode.
1069 if (this->IsEval(name)) { 1071 if (this->IsEval(name)) {
1070 classifier->RecordStrictModeFormalParameterError( 1072 classifier->RecordStrictModeFormalParameterError(
1071 scanner()->location(), MessageTemplate::kStrictEvalArguments); 1073 scanner()->location(), MessageTemplate::kStrictEvalArguments);
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1115 return Traits::EmptyIdentifier(); 1117 return Traits::EmptyIdentifier();
1116 } 1118 }
1117 } 1119 }
1118 1120
1119 1121
1120 template <class Traits> 1122 template <class Traits>
1121 typename ParserBase<Traits>::IdentifierT 1123 typename ParserBase<Traits>::IdentifierT
1122 ParserBase<Traits>::ParseIdentifierOrStrictReservedWord( 1124 ParserBase<Traits>::ParseIdentifierOrStrictReservedWord(
1123 bool is_generator, bool* is_strict_reserved, bool* ok) { 1125 bool is_generator, bool* is_strict_reserved, bool* ok) {
1124 Token::Value next = Next(); 1126 Token::Value next = Next();
1125 if (next == Token::IDENTIFIER) { 1127 if (next == Token::IDENTIFIER || (next == Token::AWAIT && !parsing_module_)) {
1126 *is_strict_reserved = false; 1128 *is_strict_reserved = false;
1127 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET || 1129 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET ||
1128 next == Token::STATIC || (next == Token::YIELD && !is_generator)) { 1130 next == Token::STATIC || (next == Token::YIELD && !is_generator)) {
1129 *is_strict_reserved = true; 1131 *is_strict_reserved = true;
1130 } else { 1132 } else {
1131 ReportUnexpectedToken(next); 1133 ReportUnexpectedToken(next);
1132 *ok = false; 1134 *ok = false;
1133 return Traits::EmptyIdentifier(); 1135 return Traits::EmptyIdentifier();
1134 } 1136 }
1135 1137
1136 IdentifierT name = this->GetSymbol(scanner()); 1138 IdentifierT name = this->GetSymbol(scanner());
1137 if (this->IsArguments(name)) scope_->RecordArgumentsUsage(); 1139 if (this->IsArguments(name)) scope_->RecordArgumentsUsage();
1138 return name; 1140 return name;
1139 } 1141 }
1140 1142
1141
1142 template <class Traits> 1143 template <class Traits>
1143 typename ParserBase<Traits>::IdentifierT 1144 typename ParserBase<Traits>::IdentifierT
1144 ParserBase<Traits>::ParseIdentifierName(bool* ok) { 1145 ParserBase<Traits>::ParseIdentifierName(bool* ok) {
1145 Token::Value next = Next(); 1146 Token::Value next = Next();
1146 if (next != Token::IDENTIFIER && next != Token::FUTURE_RESERVED_WORD && 1147 if (next != Token::IDENTIFIER && next != Token::ENUM &&
1147 next != Token::LET && next != Token::STATIC && next != Token::YIELD && 1148 next != Token::AWAIT && next != Token::LET && next != Token::STATIC &&
1148 next != Token::FUTURE_STRICT_RESERVED_WORD && 1149 next != Token::YIELD && next != Token::FUTURE_STRICT_RESERVED_WORD &&
1149 next != Token::ESCAPED_KEYWORD && 1150 next != Token::ESCAPED_KEYWORD &&
1150 next != Token::ESCAPED_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) { 1151 next != Token::ESCAPED_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) {
1151 this->ReportUnexpectedToken(next); 1152 this->ReportUnexpectedToken(next);
1152 *ok = false; 1153 *ok = false;
1153 return Traits::EmptyIdentifier(); 1154 return Traits::EmptyIdentifier();
1154 } 1155 }
1155 1156
1156 IdentifierT name = this->GetSymbol(scanner()); 1157 IdentifierT name = this->GetSymbol(scanner());
1157 if (this->IsArguments(name)) scope_->RecordArgumentsUsage(); 1158 if (this->IsArguments(name)) scope_->RecordArgumentsUsage();
1158 return name; 1159 return name;
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
1235 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory()); 1236 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory());
1236 case Token::SMI: 1237 case Token::SMI:
1237 case Token::NUMBER: 1238 case Token::NUMBER:
1238 BindingPatternUnexpectedToken(classifier); 1239 BindingPatternUnexpectedToken(classifier);
1239 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory()); 1240 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory());
1240 1241
1241 case Token::IDENTIFIER: 1242 case Token::IDENTIFIER:
1242 case Token::LET: 1243 case Token::LET:
1243 case Token::STATIC: 1244 case Token::STATIC:
1244 case Token::YIELD: 1245 case Token::YIELD:
1246 case Token::AWAIT:
1245 case Token::ESCAPED_STRICT_RESERVED_WORD: 1247 case Token::ESCAPED_STRICT_RESERVED_WORD:
1246 case Token::FUTURE_STRICT_RESERVED_WORD: { 1248 case Token::FUTURE_STRICT_RESERVED_WORD: {
1247 // Using eval or arguments in this context is OK even in strict mode. 1249 // Using eval or arguments in this context is OK even in strict mode.
1248 IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK); 1250 IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK);
1249 return this->ExpressionFromIdentifier( 1251 return this->ExpressionFromIdentifier(
1250 name, beg_pos, scanner()->location().end_pos, scope_, factory()); 1252 name, beg_pos, scanner()->location().end_pos, scope_, factory());
1251 } 1253 }
1252 1254
1253 case Token::STRING: { 1255 case Token::STRING: {
1254 BindingPatternUnexpectedToken(classifier); 1256 BindingPatternUnexpectedToken(classifier);
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after
1602 int beg_pos = peek_position(); 1604 int beg_pos = peek_position();
1603 value = this->ParseAssignmentExpression( 1605 value = this->ParseAssignmentExpression(
1604 true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 1606 true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
1605 CheckDestructuringElement(value, classifier, beg_pos, 1607 CheckDestructuringElement(value, classifier, beg_pos,
1606 scanner()->location().end_pos); 1608 scanner()->location().end_pos);
1607 1609
1608 return factory()->NewObjectLiteralProperty(name_expression, value, false, 1610 return factory()->NewObjectLiteralProperty(name_expression, value, false,
1609 *is_computed_name); 1611 *is_computed_name);
1610 } 1612 }
1611 1613
1612 if (Token::IsIdentifier(name_token, language_mode(), 1614 if (Token::IsIdentifier(name_token, language_mode(), this->is_generator(),
1613 this->is_generator()) && 1615 parsing_module_) &&
1614 (peek() == Token::COMMA || peek() == Token::RBRACE || 1616 (peek() == Token::COMMA || peek() == Token::RBRACE ||
1615 peek() == Token::ASSIGN)) { 1617 peek() == Token::ASSIGN)) {
1616 // PropertyDefinition 1618 // PropertyDefinition
1617 // IdentifierReference 1619 // IdentifierReference
1618 // CoverInitializedName 1620 // CoverInitializedName
1619 // 1621 //
1620 // CoverInitializedName 1622 // CoverInitializedName
1621 // IdentifierReference Initializer? 1623 // IdentifierReference Initializer?
1622 if (classifier->duplicate_finder() != nullptr && 1624 if (classifier->duplicate_finder() != nullptr &&
1623 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) { 1625 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) {
(...skipping 1159 matching lines...) Expand 10 before | Expand all | Expand 10 after
2783 bool ParserBase<Traits>::IsNextLetKeyword() { 2785 bool ParserBase<Traits>::IsNextLetKeyword() {
2784 DCHECK(peek() == Token::LET); 2786 DCHECK(peek() == Token::LET);
2785 Token::Value next_next = PeekAhead(); 2787 Token::Value next_next = PeekAhead();
2786 switch (next_next) { 2788 switch (next_next) {
2787 case Token::LBRACE: 2789 case Token::LBRACE:
2788 case Token::LBRACK: 2790 case Token::LBRACK:
2789 case Token::IDENTIFIER: 2791 case Token::IDENTIFIER:
2790 case Token::STATIC: 2792 case Token::STATIC:
2791 case Token::LET: // Yes, you can do let let = ... in sloppy mode 2793 case Token::LET: // Yes, you can do let let = ... in sloppy mode
2792 case Token::YIELD: 2794 case Token::YIELD:
2795 case Token::AWAIT:
2793 return true; 2796 return true;
2794 default: 2797 default:
2795 return false; 2798 return false;
2796 } 2799 }
2797 } 2800 }
2798 2801
2799 2802
2800 template <class Traits> 2803 template <class Traits>
2801 typename ParserBase<Traits>::ExpressionT 2804 typename ParserBase<Traits>::ExpressionT
2802 ParserBase<Traits>::ParseArrowFunctionLiteral( 2805 ParserBase<Traits>::ParseArrowFunctionLiteral(
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after
3112 has_seen_constructor_ = true; 3115 has_seen_constructor_ = true;
3113 return; 3116 return;
3114 } 3117 }
3115 } 3118 }
3116 3119
3117 3120
3118 } // namespace internal 3121 } // namespace internal
3119 } // namespace v8 3122 } // namespace v8
3120 3123
3121 #endif // V8_PARSING_PARSER_BASE_H 3124 #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