| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 #include <cmath> | 5 #include <cmath> |
| 6 | 6 |
| 7 #include "src/allocation.h" | 7 #include "src/allocation.h" |
| 8 #include "src/base/logging.h" | 8 #include "src/base/logging.h" |
| 9 #include "src/conversions-inl.h" | 9 #include "src/conversions-inl.h" |
| 10 #include "src/conversions.h" | 10 #include "src/conversions.h" |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 44 return PreParserIdentifier::Await(); | 44 return PreParserIdentifier::Await(); |
| 45 } else if (scanner->current_token() == | 45 } else if (scanner->current_token() == |
| 46 Token::FUTURE_STRICT_RESERVED_WORD) { | 46 Token::FUTURE_STRICT_RESERVED_WORD) { |
| 47 return PreParserIdentifier::FutureStrictReserved(); | 47 return PreParserIdentifier::FutureStrictReserved(); |
| 48 } else if (scanner->current_token() == Token::LET) { | 48 } else if (scanner->current_token() == Token::LET) { |
| 49 return PreParserIdentifier::Let(); | 49 return PreParserIdentifier::Let(); |
| 50 } else if (scanner->current_token() == Token::STATIC) { | 50 } else if (scanner->current_token() == Token::STATIC) { |
| 51 return PreParserIdentifier::Static(); | 51 return PreParserIdentifier::Static(); |
| 52 } else if (scanner->current_token() == Token::YIELD) { | 52 } else if (scanner->current_token() == Token::YIELD) { |
| 53 return PreParserIdentifier::Yield(); | 53 return PreParserIdentifier::Yield(); |
| 54 } else if (scanner->current_token() == Token::ASYNC) { |
| 55 return PreParserIdentifier::Async(); |
| 54 } | 56 } |
| 55 if (scanner->UnescapedLiteralMatches("eval", 4)) { | 57 if (scanner->UnescapedLiteralMatches("eval", 4)) { |
| 56 return PreParserIdentifier::Eval(); | 58 return PreParserIdentifier::Eval(); |
| 57 } | 59 } |
| 58 if (scanner->UnescapedLiteralMatches("arguments", 9)) { | 60 if (scanner->UnescapedLiteralMatches("arguments", 9)) { |
| 59 return PreParserIdentifier::Arguments(); | 61 return PreParserIdentifier::Arguments(); |
| 60 } | 62 } |
| 61 if (scanner->UnescapedLiteralMatches("undefined", 9)) { | 63 if (scanner->UnescapedLiteralMatches("undefined", 9)) { |
| 62 return PreParserIdentifier::Undefined(); | 64 return PreParserIdentifier::Undefined(); |
| 63 } | 65 } |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 186 return ParseHoistableDeclaration(ok); | 188 return ParseHoistableDeclaration(ok); |
| 187 case Token::CLASS: | 189 case Token::CLASS: |
| 188 return ParseClassDeclaration(ok); | 190 return ParseClassDeclaration(ok); |
| 189 case Token::CONST: | 191 case Token::CONST: |
| 190 return ParseVariableStatement(kStatementListItem, ok); | 192 return ParseVariableStatement(kStatementListItem, ok); |
| 191 case Token::LET: | 193 case Token::LET: |
| 192 if (IsNextLetKeyword()) { | 194 if (IsNextLetKeyword()) { |
| 193 return ParseVariableStatement(kStatementListItem, ok); | 195 return ParseVariableStatement(kStatementListItem, ok); |
| 194 } | 196 } |
| 195 break; | 197 break; |
| 198 case Token::ASYNC: |
| 199 if (allow_harmony_async_await() && PeekAhead() == Token::FUNCTION && |
| 200 !scanner()->HasAnyLineTerminatorAfterNext()) { |
| 201 Consume(Token::ASYNC); |
| 202 return ParseAsyncFunctionDeclaration(ok); |
| 203 } |
| 204 /* falls through */ |
| 196 default: | 205 default: |
| 197 break; | 206 break; |
| 198 } | 207 } |
| 199 return ParseStatement(kAllowLabelledFunctionStatement, ok); | 208 return ParseStatement(kAllowLabelledFunctionStatement, ok); |
| 200 } | 209 } |
| 201 | 210 |
| 202 | 211 |
| 203 void PreParser::ParseStatementList(int end_token, bool* ok, | 212 void PreParser::ParseStatementList(int end_token, bool* ok, |
| 204 Scanner::BookmarkScope* bookmark) { | 213 Scanner::BookmarkScope* bookmark) { |
| 205 // SourceElements :: | 214 // SourceElements :: |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 374 return ParseDebuggerStatement(ok); | 383 return ParseDebuggerStatement(ok); |
| 375 | 384 |
| 376 case Token::VAR: | 385 case Token::VAR: |
| 377 return ParseVariableStatement(kStatement, ok); | 386 return ParseVariableStatement(kStatement, ok); |
| 378 | 387 |
| 379 default: | 388 default: |
| 380 return ParseExpressionOrLabelledStatement(allow_function, ok); | 389 return ParseExpressionOrLabelledStatement(allow_function, ok); |
| 381 } | 390 } |
| 382 } | 391 } |
| 383 | 392 |
| 393 PreParser::Statement PreParser::ParseHoistableDeclaration( |
| 394 int pos, ParseFunctionFlags flags, bool* ok) { |
| 395 const bool is_generator = flags & ParseFunctionFlags::kIsGenerator; |
| 396 const bool is_async = flags & ParseFunctionFlags::kIsAsync; |
| 397 DCHECK(!is_generator || !is_async); |
| 384 | 398 |
| 385 PreParser::Statement PreParser::ParseHoistableDeclaration( | |
| 386 int pos, bool is_generator, bool* ok) { | |
| 387 bool is_strict_reserved = false; | 399 bool is_strict_reserved = false; |
| 388 Identifier name = ParseIdentifierOrStrictReservedWord( | 400 Identifier name = ParseIdentifierOrStrictReservedWord( |
| 389 &is_strict_reserved, CHECK_OK); | 401 &is_strict_reserved, CHECK_OK); |
| 402 |
| 403 if (V8_UNLIKELY(is_async_function() && this->IsAwait(name))) { |
| 404 ReportMessageAt(scanner()->location(), |
| 405 MessageTemplate::kAwaitBindingIdentifier); |
| 406 *ok = false; |
| 407 return Statement::Default(); |
| 408 } |
| 409 |
| 390 ParseFunctionLiteral(name, scanner()->location(), | 410 ParseFunctionLiteral(name, scanner()->location(), |
| 391 is_strict_reserved ? kFunctionNameIsStrictReserved | 411 is_strict_reserved ? kFunctionNameIsStrictReserved |
| 392 : kFunctionNameValidityUnknown, | 412 : kFunctionNameValidityUnknown, |
| 393 is_generator ? FunctionKind::kGeneratorFunction | 413 is_generator ? FunctionKind::kGeneratorFunction |
| 394 : FunctionKind::kNormalFunction, | 414 : is_async ? FunctionKind::kAsyncFunction |
| 415 : FunctionKind::kNormalFunction, |
| 395 pos, FunctionLiteral::kDeclaration, language_mode(), | 416 pos, FunctionLiteral::kDeclaration, language_mode(), |
| 396 CHECK_OK); | 417 CHECK_OK); |
| 397 return Statement::FunctionDeclaration(); | 418 return Statement::FunctionDeclaration(); |
| 398 } | 419 } |
| 399 | 420 |
| 421 PreParser::Statement PreParser::ParseAsyncFunctionDeclaration(bool* ok) { |
| 422 // AsyncFunctionDeclaration :: |
| 423 // async [no LineTerminator here] function BindingIdentifier[Await] |
| 424 // ( FormalParameters[Await] ) { AsyncFunctionBody } |
| 425 DCHECK_EQ(scanner()->current_token(), Token::ASYNC); |
| 426 int pos = position(); |
| 427 Expect(Token::FUNCTION, CHECK_OK); |
| 428 ParseFunctionFlags flags = ParseFunctionFlags::kIsAsync; |
| 429 return ParseHoistableDeclaration(pos, flags, ok); |
| 430 } |
| 400 | 431 |
| 401 PreParser::Statement PreParser::ParseHoistableDeclaration(bool* ok) { | 432 PreParser::Statement PreParser::ParseHoistableDeclaration(bool* ok) { |
| 402 // FunctionDeclaration :: | 433 // FunctionDeclaration :: |
| 403 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' | 434 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' |
| 404 // GeneratorDeclaration :: | 435 // GeneratorDeclaration :: |
| 405 // 'function' '*' Identifier '(' FormalParameterListopt ')' | 436 // 'function' '*' Identifier '(' FormalParameterListopt ')' |
| 406 // '{' FunctionBody '}' | 437 // '{' FunctionBody '}' |
| 438 |
| 407 Expect(Token::FUNCTION, CHECK_OK); | 439 Expect(Token::FUNCTION, CHECK_OK); |
| 408 int pos = position(); | 440 int pos = position(); |
| 409 bool is_generator = Check(Token::MUL); | 441 ParseFunctionFlags flags = ParseFunctionFlags::kIsNormal; |
| 410 return ParseHoistableDeclaration(pos, is_generator, CHECK_OK); | 442 if (Check(Token::MUL)) { |
| 443 flags |= ParseFunctionFlags::kIsGenerator; |
| 444 } |
| 445 return ParseHoistableDeclaration(pos, flags, ok); |
| 411 } | 446 } |
| 412 | 447 |
| 413 | 448 |
| 414 PreParser::Statement PreParser::ParseClassDeclaration(bool* ok) { | 449 PreParser::Statement PreParser::ParseClassDeclaration(bool* ok) { |
| 415 Expect(Token::CLASS, CHECK_OK); | 450 Expect(Token::CLASS, CHECK_OK); |
| 416 | 451 |
| 417 int pos = position(); | 452 int pos = position(); |
| 418 bool is_strict_reserved = false; | 453 bool is_strict_reserved = false; |
| 419 Identifier name = | 454 Identifier name = |
| 420 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); | 455 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 559 | 594 |
| 560 if (num_decl != nullptr) *num_decl = nvars; | 595 if (num_decl != nullptr) *num_decl = nvars; |
| 561 if (is_lexical != nullptr) *is_lexical = lexical; | 596 if (is_lexical != nullptr) *is_lexical = lexical; |
| 562 if (is_binding_pattern != nullptr) *is_binding_pattern = is_pattern; | 597 if (is_binding_pattern != nullptr) *is_binding_pattern = is_pattern; |
| 563 return Statement::Default(); | 598 return Statement::Default(); |
| 564 } | 599 } |
| 565 | 600 |
| 566 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) { | 601 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) { |
| 567 Consume(Token::FUNCTION); | 602 Consume(Token::FUNCTION); |
| 568 int pos = position(); | 603 int pos = position(); |
| 569 bool is_generator = Check(Token::MUL); | 604 ParseFunctionFlags flags = ParseFunctionFlags::kIsNormal; |
| 570 if (allow_harmony_restrictive_declarations() && is_generator) { | 605 if (Check(Token::MUL)) { |
| 571 PreParserTraits::ReportMessageAt( | 606 flags |= ParseFunctionFlags::kIsGenerator; |
| 572 scanner()->location(), | 607 if (allow_harmony_restrictive_declarations()) { |
| 573 MessageTemplate::kGeneratorInLegacyContext); | 608 PreParserTraits::ReportMessageAt( |
| 574 *ok = false; | 609 scanner()->location(), MessageTemplate::kGeneratorInLegacyContext); |
| 575 return Statement::Default(); | 610 *ok = false; |
| 611 return Statement::Default(); |
| 612 } |
| 576 } | 613 } |
| 577 return ParseHoistableDeclaration(pos, is_generator, ok); | 614 return ParseHoistableDeclaration(pos, flags, ok); |
| 578 } | 615 } |
| 579 | 616 |
| 580 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement( | 617 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement( |
| 581 AllowLabelledFunctionStatement allow_function, bool* ok) { | 618 AllowLabelledFunctionStatement allow_function, bool* ok) { |
| 582 // ExpressionStatement | LabelledStatement :: | 619 // ExpressionStatement | LabelledStatement :: |
| 583 // Expression ';' | 620 // Expression ';' |
| 584 // Identifier ':' Statement | 621 // Identifier ':' Statement |
| 585 | 622 |
| 586 switch (peek()) { | 623 switch (peek()) { |
| 587 case Token::FUNCTION: | 624 case Token::FUNCTION: |
| (...skipping 516 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1104 allow_duplicate_parameters, CHECK_OK); | 1141 allow_duplicate_parameters, CHECK_OK); |
| 1105 | 1142 |
| 1106 if (is_strict(language_mode)) { | 1143 if (is_strict(language_mode)) { |
| 1107 int end_position = scanner()->location().end_pos; | 1144 int end_position = scanner()->location().end_pos; |
| 1108 CheckStrictOctalLiteral(start_position, end_position, CHECK_OK); | 1145 CheckStrictOctalLiteral(start_position, end_position, CHECK_OK); |
| 1109 } | 1146 } |
| 1110 | 1147 |
| 1111 return Expression::Default(); | 1148 return Expression::Default(); |
| 1112 } | 1149 } |
| 1113 | 1150 |
| 1151 PreParser::Expression PreParser::ParseAsyncFunctionExpression(bool* ok) { |
| 1152 // AsyncFunctionDeclaration :: |
| 1153 // async [no LineTerminator here] function ( FormalParameters[Await] ) |
| 1154 // { AsyncFunctionBody } |
| 1155 // |
| 1156 // async [no LineTerminator here] function BindingIdentifier[Await] |
| 1157 // ( FormalParameters[Await] ) { AsyncFunctionBody } |
| 1158 int pos = position(); |
| 1159 Expect(Token::FUNCTION, CHECK_OK); |
| 1160 bool is_strict_reserved = false; |
| 1161 Identifier name; |
| 1162 FunctionLiteral::FunctionType type = FunctionLiteral::kAnonymousExpression; |
| 1163 |
| 1164 if (peek_any_identifier()) { |
| 1165 type = FunctionLiteral::kNamedExpression; |
| 1166 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); |
| 1167 if (this->IsAwait(name)) { |
| 1168 ReportMessageAt(scanner()->location(), |
| 1169 MessageTemplate::kAwaitBindingIdentifier); |
| 1170 *ok = false; |
| 1171 return Expression::Default(); |
| 1172 } |
| 1173 } |
| 1174 |
| 1175 ParseFunctionLiteral(name, scanner()->location(), |
| 1176 is_strict_reserved ? kFunctionNameIsStrictReserved |
| 1177 : kFunctionNameValidityUnknown, |
| 1178 FunctionKind::kAsyncFunction, pos, type, language_mode(), |
| 1179 CHECK_OK); |
| 1180 return Expression::Default(); |
| 1181 } |
| 1114 | 1182 |
| 1115 void PreParser::ParseLazyFunctionLiteralBody(bool* ok, | 1183 void PreParser::ParseLazyFunctionLiteralBody(bool* ok, |
| 1116 Scanner::BookmarkScope* bookmark) { | 1184 Scanner::BookmarkScope* bookmark) { |
| 1117 int body_start = position(); | 1185 int body_start = position(); |
| 1118 ParseStatementList(Token::RBRACE, ok, bookmark); | 1186 ParseStatementList(Token::RBRACE, ok, bookmark); |
| 1119 if (!*ok) return; | 1187 if (!*ok) return; |
| 1120 if (bookmark && bookmark->HasBeenReset()) return; | 1188 if (bookmark && bookmark->HasBeenReset()) return; |
| 1121 | 1189 |
| 1122 // Position right after terminal '}'. | 1190 // Position right after terminal '}'. |
| 1123 DCHECK_EQ(Token::RBRACE, scanner()->peek()); | 1191 DCHECK_EQ(Token::RBRACE, scanner()->peek()); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1165 } | 1233 } |
| 1166 } | 1234 } |
| 1167 | 1235 |
| 1168 ClassLiteralChecker checker(this); | 1236 ClassLiteralChecker checker(this); |
| 1169 bool has_seen_constructor = false; | 1237 bool has_seen_constructor = false; |
| 1170 | 1238 |
| 1171 Expect(Token::LBRACE, CHECK_OK); | 1239 Expect(Token::LBRACE, CHECK_OK); |
| 1172 while (peek() != Token::RBRACE) { | 1240 while (peek() != Token::RBRACE) { |
| 1173 if (Check(Token::SEMICOLON)) continue; | 1241 if (Check(Token::SEMICOLON)) continue; |
| 1174 const bool in_class = true; | 1242 const bool in_class = true; |
| 1175 const bool is_static = false; | |
| 1176 bool is_computed_name = false; // Classes do not care about computed | 1243 bool is_computed_name = false; // Classes do not care about computed |
| 1177 // property names here. | 1244 // property names here. |
| 1178 Identifier name; | 1245 Identifier name; |
| 1179 ExpressionClassifier property_classifier(this); | 1246 ExpressionClassifier property_classifier(this); |
| 1180 ParsePropertyDefinition(&checker, in_class, has_extends, is_static, | 1247 ParsePropertyDefinition(&checker, in_class, has_extends, MethodKind::Normal, |
| 1181 &is_computed_name, &has_seen_constructor, | 1248 &is_computed_name, &has_seen_constructor, |
| 1182 &property_classifier, &name, CHECK_OK); | 1249 &property_classifier, &name, CHECK_OK); |
| 1183 ValidateExpression(&property_classifier, CHECK_OK); | 1250 ValidateExpression(&property_classifier, CHECK_OK); |
| 1184 if (classifier != nullptr) { | 1251 if (classifier != nullptr) { |
| 1185 classifier->Accumulate(&property_classifier, | 1252 classifier->Accumulate(&property_classifier, |
| 1186 ExpressionClassifier::ExpressionProductions); | 1253 ExpressionClassifier::ExpressionProductions); |
| 1187 } | 1254 } |
| 1188 } | 1255 } |
| 1189 | 1256 |
| 1190 Expect(Token::RBRACE, CHECK_OK); | 1257 Expect(Token::RBRACE, CHECK_OK); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1224 } | 1291 } |
| 1225 Expect(Token::RBRACE, CHECK_OK); | 1292 Expect(Token::RBRACE, CHECK_OK); |
| 1226 return PreParserExpression::Default(); | 1293 return PreParserExpression::Default(); |
| 1227 } | 1294 } |
| 1228 | 1295 |
| 1229 #undef CHECK_OK | 1296 #undef CHECK_OK |
| 1230 | 1297 |
| 1231 | 1298 |
| 1232 } // namespace internal | 1299 } // namespace internal |
| 1233 } // namespace v8 | 1300 } // namespace v8 |
| OLD | NEW |