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

Side by Side Diff: src/parsing/preparser.cc

Issue 1841543003: [esnext] implement frontend changes for async/await proposal (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix a pointless edit 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 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
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 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 &top_factory); 116 &top_factory);
115 scope_->SetLanguageMode(language_mode); 117 scope_->SetLanguageMode(language_mode);
116 Scope* function_scope = NewScope(scope_, FUNCTION_SCOPE, kind); 118 Scope* function_scope = NewScope(scope_, FUNCTION_SCOPE, kind);
117 if (!has_simple_parameters) function_scope->SetHasNonSimpleParameters(); 119 if (!has_simple_parameters) function_scope->SetHasNonSimpleParameters();
118 PreParserFactory function_factory(NULL); 120 PreParserFactory function_factory(NULL);
119 FunctionState function_state(&function_state_, &scope_, function_scope, kind, 121 FunctionState function_state(&function_state_, &scope_, function_scope, kind,
120 &function_factory); 122 &function_factory);
121 DCHECK_EQ(Token::LBRACE, scanner()->current_token()); 123 DCHECK_EQ(Token::LBRACE, scanner()->current_token());
122 bool ok = true; 124 bool ok = true;
123 int start_position = peek_position(); 125 int start_position = peek_position();
126 function_state.set_parse_phase(FunctionParsePhase::FunctionBody);
124 ParseLazyFunctionLiteralBody(&ok, bookmark); 127 ParseLazyFunctionLiteralBody(&ok, bookmark);
125 use_counts_ = nullptr; 128 use_counts_ = nullptr;
126 if (bookmark && bookmark->HasBeenReset()) { 129 if (bookmark && bookmark->HasBeenReset()) {
127 // Do nothing, as we've just aborted scanning this function. 130 // Do nothing, as we've just aborted scanning this function.
128 } else if (stack_overflow()) { 131 } else if (stack_overflow()) {
129 return kPreParseStackOverflow; 132 return kPreParseStackOverflow;
130 } else if (!ok) { 133 } else if (!ok) {
131 ReportUnexpectedToken(scanner()->current_token()); 134 ReportUnexpectedToken(scanner()->current_token());
132 } else { 135 } else {
133 DCHECK_EQ(Token::RBRACE, scanner()->peek()); 136 DCHECK_EQ(Token::RBRACE, scanner()->peek());
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 return ParseHoistableDeclaration(ok); 189 return ParseHoistableDeclaration(ok);
187 case Token::CLASS: 190 case Token::CLASS:
188 return ParseClassDeclaration(ok); 191 return ParseClassDeclaration(ok);
189 case Token::CONST: 192 case Token::CONST:
190 return ParseVariableStatement(kStatementListItem, ok); 193 return ParseVariableStatement(kStatementListItem, ok);
191 case Token::LET: 194 case Token::LET:
192 if (IsNextLetKeyword()) { 195 if (IsNextLetKeyword()) {
193 return ParseVariableStatement(kStatementListItem, ok); 196 return ParseVariableStatement(kStatementListItem, ok);
194 } 197 }
195 break; 198 break;
199 case Token::ASYNC:
200 if (allow_harmony_async_await() && PeekAhead() == Token::FUNCTION &&
201 !scanner()->HasAnyLineTerminatorAfterNext()) {
202 Consume(Token::ASYNC);
203 return ParseAsyncFunctionDeclaration(ok);
204 }
205 /* falls through */
196 default: 206 default:
197 break; 207 break;
198 } 208 }
199 return ParseStatement(kAllowLabelledFunctionStatement, ok); 209 return ParseStatement(kAllowLabelledFunctionStatement, ok);
200 } 210 }
201 211
202 212
203 void PreParser::ParseStatementList(int end_token, bool* ok, 213 void PreParser::ParseStatementList(int end_token, bool* ok,
204 Scanner::BookmarkScope* bookmark) { 214 Scanner::BookmarkScope* bookmark) {
205 // SourceElements :: 215 // SourceElements ::
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
390 ParseFunctionLiteral(name, scanner()->location(), 400 ParseFunctionLiteral(name, scanner()->location(),
391 is_strict_reserved ? kFunctionNameIsStrictReserved 401 is_strict_reserved ? kFunctionNameIsStrictReserved
392 : kFunctionNameValidityUnknown, 402 : kFunctionNameValidityUnknown,
393 is_generator ? FunctionKind::kGeneratorFunction 403 is_generator ? FunctionKind::kGeneratorFunction
394 : FunctionKind::kNormalFunction, 404 : FunctionKind::kNormalFunction,
395 pos, FunctionLiteral::kDeclaration, language_mode(), 405 pos, FunctionLiteral::kDeclaration, language_mode(),
396 CHECK_OK); 406 CHECK_OK);
397 return Statement::FunctionDeclaration(); 407 return Statement::FunctionDeclaration();
398 } 408 }
399 409
410 PreParser::Statement PreParser::ParseAsyncFunctionDeclaration(bool* ok) {
411 // AsyncFunctionDeclaration ::
412 // async [no LineTerminator here] function BindingIdentifier[Await]
413 // ( FormalParameters[Await] ) { AsyncFunctionBody }
414 DCHECK_EQ(scanner()->current_token(), Token::ASYNC);
415 int pos = position();
416 Expect(Token::FUNCTION, CHECK_OK);
417 bool is_strict_reserved = false;
418 Identifier name =
419 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
420 if (V8_UNLIKELY(is_async_function() && this->IsAwait(name))) {
421 ReportMessageAt(scanner()->location(),
422 MessageTemplate::kAwaitBindingIdentifier);
423 *ok = false;
424 return Statement::Default();
425 }
426 ParseFunctionLiteral(name, scanner()->location(),
427 is_strict_reserved ? kFunctionNameIsStrictReserved
428 : kFunctionNameValidityUnknown,
429 FunctionKind::kAsyncFunction, pos,
430 FunctionLiteral::kDeclaration, language_mode(),
431 CHECK_OK);
432 return Statement::FunctionDeclaration();
433 }
400 434
401 PreParser::Statement PreParser::ParseHoistableDeclaration(bool* ok) { 435 PreParser::Statement PreParser::ParseHoistableDeclaration(bool* ok) {
402 // FunctionDeclaration :: 436 // FunctionDeclaration ::
403 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' 437 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
404 // GeneratorDeclaration :: 438 // GeneratorDeclaration ::
405 // 'function' '*' Identifier '(' FormalParameterListopt ')' 439 // 'function' '*' Identifier '(' FormalParameterListopt ')'
406 // '{' FunctionBody '}' 440 // '{' FunctionBody '}'
407 Expect(Token::FUNCTION, CHECK_OK); 441 Expect(Token::FUNCTION, CHECK_OK);
408 int pos = position(); 442 int pos = position();
409 bool is_generator = Check(Token::MUL); 443 bool is_generator = Check(Token::MUL);
(...skipping 654 matching lines...) Expand 10 before | Expand all | Expand 10 after
1064 PreParserFactory factory(NULL); 1098 PreParserFactory factory(NULL);
1065 FunctionState function_state(&function_state_, &scope_, function_scope, kind, 1099 FunctionState function_state(&function_state_, &scope_, function_scope, kind,
1066 &factory); 1100 &factory);
1067 DuplicateFinder duplicate_finder(scanner()->unicode_cache()); 1101 DuplicateFinder duplicate_finder(scanner()->unicode_cache());
1068 ExpressionClassifier formals_classifier(this, &duplicate_finder); 1102 ExpressionClassifier formals_classifier(this, &duplicate_finder);
1069 1103
1070 Expect(Token::LPAREN, CHECK_OK); 1104 Expect(Token::LPAREN, CHECK_OK);
1071 int start_position = scanner()->location().beg_pos; 1105 int start_position = scanner()->location().beg_pos;
1072 function_scope->set_start_position(start_position); 1106 function_scope->set_start_position(start_position);
1073 PreParserFormalParameters formals(function_scope); 1107 PreParserFormalParameters formals(function_scope);
1108 function_state.set_parse_phase(FunctionParsePhase::FormalParameters);
1074 ParseFormalParameterList(&formals, &formals_classifier, CHECK_OK); 1109 ParseFormalParameterList(&formals, &formals_classifier, CHECK_OK);
1075 Expect(Token::RPAREN, CHECK_OK); 1110 Expect(Token::RPAREN, CHECK_OK);
1076 int formals_end_position = scanner()->location().end_pos; 1111 int formals_end_position = scanner()->location().end_pos;
1077 1112
1078 CheckArityRestrictions(formals.arity, kind, formals.has_rest, start_position, 1113 CheckArityRestrictions(formals.arity, kind, formals.has_rest, start_position,
1079 formals_end_position, CHECK_OK); 1114 formals_end_position, CHECK_OK);
1080 1115
1081 // See Parser::ParseFunctionLiteral for more information about lazy parsing 1116 // See Parser::ParseFunctionLiteral for more information about lazy parsing
1082 // and lazy compilation. 1117 // and lazy compilation.
1083 bool is_lazily_parsed = (outer_is_script_scope && allow_lazy() && 1118 bool is_lazily_parsed = (outer_is_script_scope && allow_lazy() &&
1084 !function_state_->this_function_is_parenthesized()); 1119 !function_state_->this_function_is_parenthesized());
1085 1120
1086 Expect(Token::LBRACE, CHECK_OK); 1121 Expect(Token::LBRACE, CHECK_OK);
1122 function_state.set_parse_phase(FunctionParsePhase::FunctionBody);
1087 if (is_lazily_parsed) { 1123 if (is_lazily_parsed) {
1088 ParseLazyFunctionLiteralBody(CHECK_OK); 1124 ParseLazyFunctionLiteralBody(CHECK_OK);
1089 } else { 1125 } else {
1090 ParseStatementList(Token::RBRACE, CHECK_OK); 1126 ParseStatementList(Token::RBRACE, CHECK_OK);
1091 } 1127 }
1092 Expect(Token::RBRACE, CHECK_OK); 1128 Expect(Token::RBRACE, CHECK_OK);
1093 1129
1094 // Parsing the body may change the language mode in our scope. 1130 // Parsing the body may change the language mode in our scope.
1095 language_mode = function_scope->language_mode(); 1131 language_mode = function_scope->language_mode();
1096 1132
1097 // Validate name and parameter names. We can do this only after parsing the 1133 // Validate name and parameter names. We can do this only after parsing the
1098 // function, since the function can declare itself strict. 1134 // function, since the function can declare itself strict.
1099 CheckFunctionName(language_mode, function_name, function_name_validity, 1135 CheckFunctionName(language_mode, function_name, function_name_validity,
1100 function_name_location, CHECK_OK); 1136 function_name_location, CHECK_OK);
1101 const bool allow_duplicate_parameters = 1137 const bool allow_duplicate_parameters =
1102 is_sloppy(language_mode) && formals.is_simple && !IsConciseMethod(kind); 1138 is_sloppy(language_mode) && formals.is_simple && !IsConciseMethod(kind);
1103 ValidateFormalParameters(&formals_classifier, language_mode, 1139 ValidateFormalParameters(&formals_classifier, language_mode,
1104 allow_duplicate_parameters, CHECK_OK); 1140 allow_duplicate_parameters, CHECK_OK);
1105 1141
1106 if (is_strict(language_mode)) { 1142 if (is_strict(language_mode)) {
1107 int end_position = scanner()->location().end_pos; 1143 int end_position = scanner()->location().end_pos;
1108 CheckStrictOctalLiteral(start_position, end_position, CHECK_OK); 1144 CheckStrictOctalLiteral(start_position, end_position, CHECK_OK);
1109 } 1145 }
1110 1146
1111 return Expression::Default(); 1147 return Expression::Default();
1112 } 1148 }
1113 1149
1150 PreParser::Expression PreParser::ParseAsyncFunctionExpression(bool* ok) {
1151 // AsyncFunctionDeclaration ::
1152 // async [no LineTerminator here] function ( FormalParameters[Await] )
1153 // { AsyncFunctionBody }
1154 //
1155 // async [no LineTerminator here] function BindingIdentifier[Await]
1156 // ( FormalParameters[Await] ) { AsyncFunctionBody }
1157 int pos = position();
1158 Expect(Token::FUNCTION, CHECK_OK);
1159 bool is_strict_reserved = false;
1160 Identifier name;
1161 FunctionLiteral::FunctionType type = FunctionLiteral::kAnonymousExpression;
1162
1163 if (peek_any_identifier()) {
1164 type = FunctionLiteral::kNamedExpression;
1165 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
1166 if (this->IsAwait(name)) {
1167 ReportMessageAt(scanner()->location(),
1168 MessageTemplate::kAwaitBindingIdentifier);
1169 *ok = false;
1170 return Expression::Default();
1171 }
1172 }
1173
1174 ParseFunctionLiteral(name, scanner()->location(),
1175 is_strict_reserved ? kFunctionNameIsStrictReserved
1176 : kFunctionNameValidityUnknown,
1177 FunctionKind::kAsyncFunction, pos, type, language_mode(),
1178 CHECK_OK);
1179 return Expression::Default();
1180 }
1114 1181
1115 void PreParser::ParseLazyFunctionLiteralBody(bool* ok, 1182 void PreParser::ParseLazyFunctionLiteralBody(bool* ok,
1116 Scanner::BookmarkScope* bookmark) { 1183 Scanner::BookmarkScope* bookmark) {
1117 int body_start = position(); 1184 int body_start = position();
1118 ParseStatementList(Token::RBRACE, ok, bookmark); 1185 ParseStatementList(Token::RBRACE, ok, bookmark);
1119 if (!*ok) return; 1186 if (!*ok) return;
1120 if (bookmark && bookmark->HasBeenReset()) return; 1187 if (bookmark && bookmark->HasBeenReset()) return;
1121 1188
1122 // Position right after terminal '}'. 1189 // Position right after terminal '}'.
1123 DCHECK_EQ(Token::RBRACE, scanner()->peek()); 1190 DCHECK_EQ(Token::RBRACE, scanner()->peek());
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1165 } 1232 }
1166 } 1233 }
1167 1234
1168 ClassLiteralChecker checker(this); 1235 ClassLiteralChecker checker(this);
1169 bool has_seen_constructor = false; 1236 bool has_seen_constructor = false;
1170 1237
1171 Expect(Token::LBRACE, CHECK_OK); 1238 Expect(Token::LBRACE, CHECK_OK);
1172 while (peek() != Token::RBRACE) { 1239 while (peek() != Token::RBRACE) {
1173 if (Check(Token::SEMICOLON)) continue; 1240 if (Check(Token::SEMICOLON)) continue;
1174 const bool in_class = true; 1241 const bool in_class = true;
1175 const bool is_static = false;
1176 bool is_computed_name = false; // Classes do not care about computed 1242 bool is_computed_name = false; // Classes do not care about computed
1177 // property names here. 1243 // property names here.
1178 Identifier name; 1244 Identifier name;
1179 ExpressionClassifier property_classifier(this); 1245 ExpressionClassifier property_classifier(this);
1180 ParsePropertyDefinition(&checker, in_class, has_extends, is_static, 1246 ParsePropertyDefinition(&checker, in_class, has_extends, MethodKind::Normal,
1181 &is_computed_name, &has_seen_constructor, 1247 &is_computed_name, &has_seen_constructor,
1182 &property_classifier, &name, CHECK_OK); 1248 &property_classifier, &name, CHECK_OK);
1183 ValidateExpression(&property_classifier, CHECK_OK); 1249 ValidateExpression(&property_classifier, CHECK_OK);
1184 if (classifier != nullptr) { 1250 if (classifier != nullptr) {
1185 classifier->Accumulate(&property_classifier, 1251 classifier->Accumulate(&property_classifier,
1186 ExpressionClassifier::ExpressionProductions); 1252 ExpressionClassifier::ExpressionProductions);
1187 } 1253 }
1188 } 1254 }
1189 1255
1190 Expect(Token::RBRACE, CHECK_OK); 1256 Expect(Token::RBRACE, CHECK_OK);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1224 } 1290 }
1225 Expect(Token::RBRACE, CHECK_OK); 1291 Expect(Token::RBRACE, CHECK_OK);
1226 return PreParserExpression::Default(); 1292 return PreParserExpression::Default();
1227 } 1293 }
1228 1294
1229 #undef CHECK_OK 1295 #undef CHECK_OK
1230 1296
1231 1297
1232 } // namespace internal 1298 } // namespace internal
1233 } // namespace v8 1299 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698