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

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: Second pass Created 4 years, 10 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 431 matching lines...) Expand 10 before | Expand all | Expand 10 after
442 if (scanner()->HasAnyLineTerminatorBeforeNext() || 442 if (scanner()->HasAnyLineTerminatorBeforeNext() ||
443 tok == Token::RBRACE || 443 tok == Token::RBRACE ||
444 tok == Token::EOS) { 444 tok == Token::EOS) {
445 return; 445 return;
446 } 446 }
447 Expect(Token::SEMICOLON, ok); 447 Expect(Token::SEMICOLON, ok);
448 } 448 }
449 449
450 bool peek_any_identifier() { 450 bool peek_any_identifier() {
451 Token::Value next = peek(); 451 Token::Value next = peek();
452 return next == Token::IDENTIFIER || next == Token::FUTURE_RESERVED_WORD || 452 return next == Token::IDENTIFIER || next == Token::AWAIT ||
453 next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET || 453 next == Token::ENUM || next == Token::FUTURE_STRICT_RESERVED_WORD ||
454 next == Token::STATIC || next == Token::YIELD; 454 next == Token::LET || next == Token::STATIC || next == Token::YIELD;
455 } 455 }
456 456
457 bool CheckContextualKeyword(Vector<const char> keyword) { 457 bool CheckContextualKeyword(Vector<const char> keyword) {
458 if (PeekContextualKeyword(keyword)) { 458 if (PeekContextualKeyword(keyword)) {
459 Consume(Token::IDENTIFIER); 459 Consume(Token::IDENTIFIER);
460 return true; 460 return true;
461 } 461 }
462 return false; 462 return false;
463 } 463 }
464 464
(...skipping 463 matching lines...) Expand 10 before | Expand all | Expand 10 after
928 // so never lazily compile it. 928 // so never lazily compile it.
929 bool parenthesized_function_; 929 bool parenthesized_function_;
930 930
931 Scope* scope_; // Scope stack. 931 Scope* scope_; // Scope stack.
932 FunctionState* function_state_; // Function state stack. 932 FunctionState* function_state_; // Function state stack.
933 v8::Extension* extension_; 933 v8::Extension* extension_;
934 FuncNameInferrer* fni_; 934 FuncNameInferrer* fni_;
935 AstValueFactory* ast_value_factory_; // Not owned. 935 AstValueFactory* ast_value_factory_; // Not owned.
936 ParserRecorder* log_; 936 ParserRecorder* log_;
937 Mode mode_; 937 Mode mode_;
938 bool parsing_module_;
adamk 2016/02/24 19:13:25 Please initialize this to false in the constructor
938 uintptr_t stack_limit_; 939 uintptr_t stack_limit_;
939 940
940 private: 941 private:
941 Zone* zone_; 942 Zone* zone_;
942 943
943 Scanner* scanner_; 944 Scanner* scanner_;
944 bool stack_overflow_; 945 bool stack_overflow_;
945 946
946 bool allow_lazy_; 947 bool allow_lazy_;
947 bool allow_natives_; 948 bool allow_natives_;
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1003 *arg = nullptr; 1004 *arg = nullptr;
1004 break; 1005 break;
1005 case Token::STRING: 1006 case Token::STRING:
1006 *message = MessageTemplate::kUnexpectedTokenString; 1007 *message = MessageTemplate::kUnexpectedTokenString;
1007 *arg = nullptr; 1008 *arg = nullptr;
1008 break; 1009 break;
1009 case Token::IDENTIFIER: 1010 case Token::IDENTIFIER:
1010 *message = MessageTemplate::kUnexpectedTokenIdentifier; 1011 *message = MessageTemplate::kUnexpectedTokenIdentifier;
1011 *arg = nullptr; 1012 *arg = nullptr;
1012 break; 1013 break;
1013 case Token::FUTURE_RESERVED_WORD: 1014 case Token::AWAIT:
1015 case Token::ENUM:
1014 *message = MessageTemplate::kUnexpectedReserved; 1016 *message = MessageTemplate::kUnexpectedReserved;
1015 *arg = nullptr; 1017 *arg = nullptr;
1016 break; 1018 break;
1017 case Token::LET: 1019 case Token::LET:
1018 case Token::STATIC: 1020 case Token::STATIC:
1019 case Token::YIELD: 1021 case Token::YIELD:
1020 case Token::FUTURE_STRICT_RESERVED_WORD: 1022 case Token::FUTURE_STRICT_RESERVED_WORD:
1021 *message = is_strict(language_mode()) 1023 *message = is_strict(language_mode())
1022 ? MessageTemplate::kUnexpectedStrictReserved 1024 ? MessageTemplate::kUnexpectedStrictReserved
1023 : MessageTemplate::kUnexpectedTokenIdentifier; 1025 : MessageTemplate::kUnexpectedTokenIdentifier;
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1074 1076
1075 return result; 1077 return result;
1076 } 1078 }
1077 1079
1078 1080
1079 template <class Traits> 1081 template <class Traits>
1080 typename ParserBase<Traits>::IdentifierT 1082 typename ParserBase<Traits>::IdentifierT
1081 ParserBase<Traits>::ParseAndClassifyIdentifier(ExpressionClassifier* classifier, 1083 ParserBase<Traits>::ParseAndClassifyIdentifier(ExpressionClassifier* classifier,
1082 bool* ok) { 1084 bool* ok) {
1083 Token::Value next = Next(); 1085 Token::Value next = Next();
1084 if (next == Token::IDENTIFIER) { 1086 if (next == Token::IDENTIFIER || (next == Token::AWAIT && !parsing_module_)) {
1085 IdentifierT name = this->GetSymbol(scanner()); 1087 IdentifierT name = this->GetSymbol(scanner());
1086 // When this function is used to read a formal parameter, we don't always 1088 // When this function is used to read a formal parameter, we don't always
1087 // know whether the function is going to be strict or sloppy. Indeed for 1089 // know whether the function is going to be strict or sloppy. Indeed for
1088 // arrow functions we don't always know that the identifier we are reading 1090 // arrow functions we don't always know that the identifier we are reading
1089 // is actually a formal parameter. Therefore besides the errors that we 1091 // is actually a formal parameter. Therefore besides the errors that we
1090 // must detect because we know we're in strict mode, we also record any 1092 // must detect because we know we're in strict mode, we also record any
1091 // error that we might make in the future once we know the language mode. 1093 // error that we might make in the future once we know the language mode.
1092 if (this->IsEval(name)) { 1094 if (this->IsEval(name)) {
1093 classifier->RecordStrictModeFormalParameterError( 1095 classifier->RecordStrictModeFormalParameterError(
1094 scanner()->location(), MessageTemplate::kStrictEvalArguments); 1096 scanner()->location(), MessageTemplate::kStrictEvalArguments);
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1151 return Traits::EmptyIdentifier(); 1153 return Traits::EmptyIdentifier();
1152 } 1154 }
1153 } 1155 }
1154 1156
1155 1157
1156 template <class Traits> 1158 template <class Traits>
1157 typename ParserBase<Traits>::IdentifierT 1159 typename ParserBase<Traits>::IdentifierT
1158 ParserBase<Traits>::ParseIdentifierOrStrictReservedWord( 1160 ParserBase<Traits>::ParseIdentifierOrStrictReservedWord(
1159 bool is_generator, bool* is_strict_reserved, bool* ok) { 1161 bool is_generator, bool* is_strict_reserved, bool* ok) {
1160 Token::Value next = Next(); 1162 Token::Value next = Next();
1161 if (next == Token::IDENTIFIER) { 1163 if (next == Token::IDENTIFIER || (next == Token::AWAIT && !parsing_module_)) {
1162 *is_strict_reserved = false; 1164 *is_strict_reserved = false;
1163 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET || 1165 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET ||
1164 next == Token::STATIC || (next == Token::YIELD && !is_generator)) { 1166 next == Token::STATIC || (next == Token::YIELD && !is_generator)) {
1165 *is_strict_reserved = true; 1167 *is_strict_reserved = true;
1166 } else { 1168 } else {
1167 ReportUnexpectedToken(next); 1169 ReportUnexpectedToken(next);
1168 *ok = false; 1170 *ok = false;
1169 return Traits::EmptyIdentifier(); 1171 return Traits::EmptyIdentifier();
1170 } 1172 }
1171 1173
1172 IdentifierT name = this->GetSymbol(scanner()); 1174 IdentifierT name = this->GetSymbol(scanner());
1173 if (this->IsArguments(name)) scope_->RecordArgumentsUsage(); 1175 if (this->IsArguments(name)) scope_->RecordArgumentsUsage();
1174 return name; 1176 return name;
1175 } 1177 }
1176 1178
1177
1178 template <class Traits> 1179 template <class Traits>
1179 typename ParserBase<Traits>::IdentifierT 1180 typename ParserBase<Traits>::IdentifierT
1180 ParserBase<Traits>::ParseIdentifierName(bool* ok) { 1181 ParserBase<Traits>::ParseIdentifierName(bool* ok) {
1181 Token::Value next = Next(); 1182 Token::Value next = Next();
1182 if (next != Token::IDENTIFIER && next != Token::FUTURE_RESERVED_WORD && 1183 if (next != Token::IDENTIFIER && next != Token::ENUM &&
1183 next != Token::LET && next != Token::STATIC && next != Token::YIELD && 1184 next != Token::AWAIT && next != Token::LET && next != Token::STATIC &&
1184 next != Token::FUTURE_STRICT_RESERVED_WORD && 1185 next != Token::YIELD && next != Token::FUTURE_STRICT_RESERVED_WORD &&
1185 next != Token::ESCAPED_KEYWORD && 1186 next != Token::ESCAPED_KEYWORD &&
1186 next != Token::ESCAPED_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) { 1187 next != Token::ESCAPED_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) {
1187 this->ReportUnexpectedToken(next); 1188 this->ReportUnexpectedToken(next);
1188 *ok = false; 1189 *ok = false;
1189 return Traits::EmptyIdentifier(); 1190 return Traits::EmptyIdentifier();
1190 } 1191 }
1191 1192
1192 IdentifierT name = this->GetSymbol(scanner()); 1193 IdentifierT name = this->GetSymbol(scanner());
1193 if (this->IsArguments(name)) scope_->RecordArgumentsUsage(); 1194 if (this->IsArguments(name)) scope_->RecordArgumentsUsage();
1194 return name; 1195 return name;
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1281 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory()); 1282 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory());
1282 case Token::SMI: 1283 case Token::SMI:
1283 case Token::NUMBER: 1284 case Token::NUMBER:
1284 BindingPatternUnexpectedToken(classifier); 1285 BindingPatternUnexpectedToken(classifier);
1285 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory()); 1286 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory());
1286 1287
1287 case Token::IDENTIFIER: 1288 case Token::IDENTIFIER:
1288 case Token::LET: 1289 case Token::LET:
1289 case Token::STATIC: 1290 case Token::STATIC:
1290 case Token::YIELD: 1291 case Token::YIELD:
1292 case Token::AWAIT:
1291 case Token::ESCAPED_STRICT_RESERVED_WORD: 1293 case Token::ESCAPED_STRICT_RESERVED_WORD:
1292 case Token::FUTURE_STRICT_RESERVED_WORD: { 1294 case Token::FUTURE_STRICT_RESERVED_WORD: {
1293 // Using eval or arguments in this context is OK even in strict mode. 1295 // Using eval or arguments in this context is OK even in strict mode.
1294 IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK); 1296 IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK);
1295 return this->ExpressionFromIdentifier( 1297 return this->ExpressionFromIdentifier(
1296 name, beg_pos, scanner()->location().end_pos, scope_, factory()); 1298 name, beg_pos, scanner()->location().end_pos, scope_, factory());
1297 } 1299 }
1298 1300
1299 case Token::STRING: { 1301 case Token::STRING: {
1300 BindingPatternUnexpectedToken(classifier); 1302 BindingPatternUnexpectedToken(classifier);
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after
1665 int beg_pos = peek_position(); 1667 int beg_pos = peek_position();
1666 value = this->ParseAssignmentExpression( 1668 value = this->ParseAssignmentExpression(
1667 true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 1669 true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
1668 CheckDestructuringElement(value, classifier, beg_pos, 1670 CheckDestructuringElement(value, classifier, beg_pos,
1669 scanner()->location().end_pos); 1671 scanner()->location().end_pos);
1670 1672
1671 return factory()->NewObjectLiteralProperty(name_expression, value, false, 1673 return factory()->NewObjectLiteralProperty(name_expression, value, false,
1672 *is_computed_name); 1674 *is_computed_name);
1673 } 1675 }
1674 1676
1675 if (Token::IsIdentifier(name_token, language_mode(), 1677 if (Token::IsIdentifier(name_token, language_mode(), this->is_generator(),
1676 this->is_generator()) && 1678 parsing_module_) &&
1677 (peek() == Token::COMMA || peek() == Token::RBRACE || 1679 (peek() == Token::COMMA || peek() == Token::RBRACE ||
1678 peek() == Token::ASSIGN)) { 1680 peek() == Token::ASSIGN)) {
1679 // PropertyDefinition 1681 // PropertyDefinition
1680 // IdentifierReference 1682 // IdentifierReference
1681 // CoverInitializedName 1683 // CoverInitializedName
1682 // 1684 //
1683 // CoverInitializedName 1685 // CoverInitializedName
1684 // IdentifierReference Initializer? 1686 // IdentifierReference Initializer?
1685 if (classifier->duplicate_finder() != nullptr && 1687 if (classifier->duplicate_finder() != nullptr &&
1686 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) { 1688 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) {
(...skipping 1331 matching lines...) Expand 10 before | Expand all | Expand 10 after
3018 return false; 3020 return false;
3019 } 3021 }
3020 Token::Value next_next = PeekAhead(); 3022 Token::Value next_next = PeekAhead();
3021 switch (next_next) { 3023 switch (next_next) {
3022 case Token::LBRACE: 3024 case Token::LBRACE:
3023 case Token::LBRACK: 3025 case Token::LBRACK:
3024 case Token::IDENTIFIER: 3026 case Token::IDENTIFIER:
3025 case Token::STATIC: 3027 case Token::STATIC:
3026 case Token::LET: // Yes, you can do let let = ... in sloppy mode 3028 case Token::LET: // Yes, you can do let let = ... in sloppy mode
3027 case Token::YIELD: 3029 case Token::YIELD:
3030 case Token::AWAIT:
3028 return true; 3031 return true;
3029 default: 3032 default:
3030 return false; 3033 return false;
3031 } 3034 }
3032 } 3035 }
3033 3036
3034 3037
3035 template <class Traits> 3038 template <class Traits>
3036 typename ParserBase<Traits>::ExpressionT 3039 typename ParserBase<Traits>::ExpressionT
3037 ParserBase<Traits>::ParseArrowFunctionLiteral( 3040 ParserBase<Traits>::ParseArrowFunctionLiteral(
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after
3372 has_seen_constructor_ = true; 3375 has_seen_constructor_ = true;
3373 return; 3376 return;
3374 } 3377 }
3375 } 3378 }
3376 3379
3377 3380
3378 } // namespace internal 3381 } // namespace internal
3379 } // namespace v8 3382 } // namespace v8
3380 3383
3381 #endif // V8_PARSING_PARSER_BASE_H 3384 #endif // V8_PARSING_PARSER_BASE_H
OLDNEW
« no previous file with comments | « src/parsing/parser.cc ('k') | src/parsing/preparser.h » ('j') | src/parsing/preparser.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698