OLD | NEW |
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 #include "src/parsing/parser.h" | 5 #include "src/parsing/parser.h" |
6 | 6 |
7 #include "src/api.h" | 7 #include "src/api.h" |
8 #include "src/ast/ast.h" | 8 #include "src/ast/ast.h" |
9 #include "src/ast/ast-expression-rewriter.h" | 9 #include "src/ast/ast-expression-rewriter.h" |
10 #include "src/ast/ast-expression-visitor.h" | 10 #include "src/ast/ast-expression-visitor.h" |
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
323 | 323 |
324 | 324 |
325 bool ParserTraits::IsEvalOrArguments(const AstRawString* identifier) const { | 325 bool ParserTraits::IsEvalOrArguments(const AstRawString* identifier) const { |
326 return IsEval(identifier) || IsArguments(identifier); | 326 return IsEval(identifier) || IsArguments(identifier); |
327 } | 327 } |
328 | 328 |
329 bool ParserTraits::IsUndefined(const AstRawString* identifier) const { | 329 bool ParserTraits::IsUndefined(const AstRawString* identifier) const { |
330 return identifier == parser_->ast_value_factory()->undefined_string(); | 330 return identifier == parser_->ast_value_factory()->undefined_string(); |
331 } | 331 } |
332 | 332 |
| 333 bool ParserTraits::IsAwait(const AstRawString* identifier) const { |
| 334 return identifier == parser_->ast_value_factory()->await_string(); |
| 335 } |
| 336 |
333 bool ParserTraits::IsPrototype(const AstRawString* identifier) const { | 337 bool ParserTraits::IsPrototype(const AstRawString* identifier) const { |
334 return identifier == parser_->ast_value_factory()->prototype_string(); | 338 return identifier == parser_->ast_value_factory()->prototype_string(); |
335 } | 339 } |
336 | 340 |
337 | 341 |
338 bool ParserTraits::IsConstructor(const AstRawString* identifier) const { | 342 bool ParserTraits::IsConstructor(const AstRawString* identifier) const { |
339 return identifier == parser_->ast_value_factory()->constructor_string(); | 343 return identifier == parser_->ast_value_factory()->constructor_string(); |
340 } | 344 } |
341 | 345 |
342 | 346 |
(...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
791 set_allow_tailcalls(FLAG_harmony_tailcalls && !info->is_native() && | 795 set_allow_tailcalls(FLAG_harmony_tailcalls && !info->is_native() && |
792 info->isolate()->is_tail_call_elimination_enabled()); | 796 info->isolate()->is_tail_call_elimination_enabled()); |
793 set_allow_harmony_do_expressions(FLAG_harmony_do_expressions); | 797 set_allow_harmony_do_expressions(FLAG_harmony_do_expressions); |
794 set_allow_harmony_for_in(FLAG_harmony_for_in); | 798 set_allow_harmony_for_in(FLAG_harmony_for_in); |
795 set_allow_harmony_function_name(FLAG_harmony_function_name); | 799 set_allow_harmony_function_name(FLAG_harmony_function_name); |
796 set_allow_harmony_function_sent(FLAG_harmony_function_sent); | 800 set_allow_harmony_function_sent(FLAG_harmony_function_sent); |
797 set_allow_harmony_restrictive_declarations( | 801 set_allow_harmony_restrictive_declarations( |
798 FLAG_harmony_restrictive_declarations); | 802 FLAG_harmony_restrictive_declarations); |
799 set_allow_harmony_exponentiation_operator( | 803 set_allow_harmony_exponentiation_operator( |
800 FLAG_harmony_exponentiation_operator); | 804 FLAG_harmony_exponentiation_operator); |
| 805 set_allow_harmony_async_await(FLAG_harmony_async_await); |
801 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; | 806 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; |
802 ++feature) { | 807 ++feature) { |
803 use_counts_[feature] = 0; | 808 use_counts_[feature] = 0; |
804 } | 809 } |
805 if (info->ast_value_factory() == NULL) { | 810 if (info->ast_value_factory() == NULL) { |
806 // info takes ownership of AstValueFactory. | 811 // info takes ownership of AstValueFactory. |
807 info->set_ast_value_factory(new AstValueFactory(zone(), info->hash_seed())); | 812 info->set_ast_value_factory(new AstValueFactory(zone(), info->hash_seed())); |
808 info->set_ast_value_factory_owned(); | 813 info->set_ast_value_factory_owned(); |
809 ast_value_factory_ = info->ast_value_factory(); | 814 ast_value_factory_ = info->ast_value_factory(); |
810 } | 815 } |
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1066 FunctionState function_state(&function_state_, &scope_, scope, | 1071 FunctionState function_state(&function_state_, &scope_, scope, |
1067 shared_info->kind(), &function_factory); | 1072 shared_info->kind(), &function_factory); |
1068 DCHECK(is_sloppy(scope->language_mode()) || | 1073 DCHECK(is_sloppy(scope->language_mode()) || |
1069 is_strict(info->language_mode())); | 1074 is_strict(info->language_mode())); |
1070 DCHECK(info->language_mode() == shared_info->language_mode()); | 1075 DCHECK(info->language_mode() == shared_info->language_mode()); |
1071 FunctionLiteral::FunctionType function_type = | 1076 FunctionLiteral::FunctionType function_type = |
1072 ComputeFunctionType(shared_info); | 1077 ComputeFunctionType(shared_info); |
1073 bool ok = true; | 1078 bool ok = true; |
1074 | 1079 |
1075 if (shared_info->is_arrow()) { | 1080 if (shared_info->is_arrow()) { |
| 1081 bool is_async = allow_harmony_async_await() && |
| 1082 peek() == Token::IDENTIFIER && |
| 1083 PeekContextualKeyword(CStrVector("async")) && |
| 1084 !scanner()->HasAnyLineTerminatorAfterNext(); |
| 1085 |
| 1086 if (is_async) { |
| 1087 Consume(Token::IDENTIFIER); |
| 1088 DCHECK(peek_any_identifier() || peek() == Token::LPAREN); |
| 1089 } |
| 1090 |
1076 // TODO(adamk): We should construct this scope from the ScopeInfo. | 1091 // TODO(adamk): We should construct this scope from the ScopeInfo. |
1077 Scope* scope = | 1092 Scope* scope = |
1078 NewScope(scope_, FUNCTION_SCOPE, FunctionKind::kArrowFunction); | 1093 NewScope(scope_, FUNCTION_SCOPE, FunctionKind::kArrowFunction); |
1079 | 1094 |
1080 // These two bits only need to be explicitly set because we're | 1095 // These two bits only need to be explicitly set because we're |
1081 // not passing the ScopeInfo to the Scope constructor. | 1096 // not passing the ScopeInfo to the Scope constructor. |
1082 // TODO(adamk): Remove these calls once the above NewScope call | 1097 // TODO(adamk): Remove these calls once the above NewScope call |
1083 // passes the ScopeInfo. | 1098 // passes the ScopeInfo. |
1084 if (shared_info->scope_info()->CallsEval()) { | 1099 if (shared_info->scope_info()->CallsEval()) { |
1085 scope->RecordEvalCall(); | 1100 scope->RecordEvalCall(); |
(...skipping 20 matching lines...) Expand all Loading... |
1106 DeclareFormalParameter(formals.scope, formals.at(0), | 1121 DeclareFormalParameter(formals.scope, formals.at(0), |
1107 &formals_classifier); | 1122 &formals_classifier); |
1108 } | 1123 } |
1109 } | 1124 } |
1110 } | 1125 } |
1111 | 1126 |
1112 if (ok) { | 1127 if (ok) { |
1113 checkpoint.Restore(&formals.materialized_literals_count); | 1128 checkpoint.Restore(&formals.materialized_literals_count); |
1114 // Pass `accept_IN=true` to ParseArrowFunctionLiteral --- This should | 1129 // Pass `accept_IN=true` to ParseArrowFunctionLiteral --- This should |
1115 // not be observable, or else the preparser would have failed. | 1130 // not be observable, or else the preparser would have failed. |
1116 Expression* expression = | 1131 Expression* expression = ParseArrowFunctionLiteral( |
1117 ParseArrowFunctionLiteral(true, formals, formals_classifier, &ok); | 1132 true, formals, is_async, formals_classifier, &ok); |
1118 if (ok) { | 1133 if (ok) { |
1119 // Scanning must end at the same position that was recorded | 1134 // Scanning must end at the same position that was recorded |
1120 // previously. If not, parsing has been interrupted due to a stack | 1135 // previously. If not, parsing has been interrupted due to a stack |
1121 // overflow, at which point the partially parsed arrow function | 1136 // overflow, at which point the partially parsed arrow function |
1122 // concise body happens to be a valid expression. This is a problem | 1137 // concise body happens to be a valid expression. This is a problem |
1123 // only for arrow functions with single expression bodies, since there | 1138 // only for arrow functions with single expression bodies, since there |
1124 // is no end token such as "}" for normal functions. | 1139 // is no end token such as "}" for normal functions. |
1125 if (scanner()->location().end_pos == shared_info->end_position()) { | 1140 if (scanner()->location().end_pos == shared_info->end_position()) { |
1126 // The pre-parser saw an arrow function here, so the full parser | 1141 // The pre-parser saw an arrow function here, so the full parser |
1127 // must produce a FunctionLiteral. | 1142 // must produce a FunctionLiteral. |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1246 | 1261 |
1247 return 0; | 1262 return 0; |
1248 } | 1263 } |
1249 | 1264 |
1250 | 1265 |
1251 Statement* Parser::ParseStatementListItem(bool* ok) { | 1266 Statement* Parser::ParseStatementListItem(bool* ok) { |
1252 // (Ecma 262 6th Edition, 13.1): | 1267 // (Ecma 262 6th Edition, 13.1): |
1253 // StatementListItem: | 1268 // StatementListItem: |
1254 // Statement | 1269 // Statement |
1255 // Declaration | 1270 // Declaration |
1256 | 1271 const Token::Value peeked = peek(); |
1257 switch (peek()) { | 1272 switch (peeked) { |
1258 case Token::FUNCTION: | 1273 case Token::FUNCTION: |
1259 return ParseHoistableDeclaration(NULL, ok); | 1274 return ParseHoistableDeclaration(NULL, ok); |
1260 case Token::CLASS: | 1275 case Token::CLASS: |
1261 Consume(Token::CLASS); | 1276 Consume(Token::CLASS); |
1262 return ParseClassDeclaration(NULL, ok); | 1277 return ParseClassDeclaration(NULL, ok); |
1263 case Token::CONST: | 1278 case Token::CONST: |
1264 return ParseVariableStatement(kStatementListItem, NULL, ok); | 1279 return ParseVariableStatement(kStatementListItem, NULL, ok); |
1265 case Token::VAR: | 1280 case Token::VAR: |
1266 return ParseVariableStatement(kStatementListItem, NULL, ok); | 1281 return ParseVariableStatement(kStatementListItem, NULL, ok); |
1267 case Token::LET: | 1282 case Token::LET: |
1268 if (IsNextLetKeyword()) { | 1283 if (IsNextLetKeyword()) { |
1269 return ParseVariableStatement(kStatementListItem, NULL, ok); | 1284 return ParseVariableStatement(kStatementListItem, NULL, ok); |
1270 } | 1285 } |
1271 break; | 1286 break; |
| 1287 case Token::IDENTIFIER: |
| 1288 if (allow_harmony_async_await() && |
| 1289 PeekContextualKeyword(CStrVector("async")) && |
| 1290 PeekAhead() == Token::FUNCTION && |
| 1291 !scanner()->HasAnyLineTerminatorAfterNext()) { |
| 1292 Consume(Token::IDENTIFIER); |
| 1293 return ParseAsyncFunctionDeclaration(NULL, ok); |
| 1294 } |
| 1295 /* falls through */ |
1272 default: | 1296 default: |
1273 break; | 1297 break; |
1274 } | 1298 } |
1275 return ParseStatement(NULL, kAllowLabelledFunctionStatement, ok); | 1299 return ParseStatement(NULL, kAllowLabelledFunctionStatement, ok); |
1276 } | 1300 } |
1277 | 1301 |
1278 | 1302 |
1279 Statement* Parser::ParseModuleItem(bool* ok) { | 1303 Statement* Parser::ParseModuleItem(bool* ok) { |
1280 // (Ecma 262 6th Edition, 15.2): | 1304 // (Ecma 262 6th Edition, 15.2): |
1281 // ModuleItem : | 1305 // ModuleItem : |
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1551 // GeneratorDeclaration[+Default] :: | 1575 // GeneratorDeclaration[+Default] :: |
1552 // 'function' '*' '(' FormalParameters ')' '{' FunctionBody '}' | 1576 // 'function' '*' '(' FormalParameters ')' '{' FunctionBody '}' |
1553 default_export = ParseFunctionLiteral( | 1577 default_export = ParseFunctionLiteral( |
1554 default_string, Scanner::Location::invalid(), | 1578 default_string, Scanner::Location::invalid(), |
1555 kSkipFunctionNameCheck, | 1579 kSkipFunctionNameCheck, |
1556 is_generator ? FunctionKind::kGeneratorFunction | 1580 is_generator ? FunctionKind::kGeneratorFunction |
1557 : FunctionKind::kNormalFunction, | 1581 : FunctionKind::kNormalFunction, |
1558 pos, FunctionLiteral::kDeclaration, language_mode(), CHECK_OK); | 1582 pos, FunctionLiteral::kDeclaration, language_mode(), CHECK_OK); |
1559 result = factory()->NewEmptyStatement(RelocInfo::kNoPosition); | 1583 result = factory()->NewEmptyStatement(RelocInfo::kNoPosition); |
1560 } else { | 1584 } else { |
1561 result = ParseHoistableDeclaration(pos, is_generator, &names, CHECK_OK); | 1585 result = ParseHoistableDeclaration( |
| 1586 pos, is_generator ? ParseFunctionFlags::kIsGenerator |
| 1587 : ParseFunctionFlags::kIsNormal, |
| 1588 &names, CHECK_OK); |
1562 } | 1589 } |
1563 break; | 1590 break; |
1564 } | 1591 } |
1565 | 1592 |
1566 case Token::CLASS: | 1593 case Token::CLASS: |
1567 Consume(Token::CLASS); | 1594 Consume(Token::CLASS); |
1568 if (peek() == Token::EXTENDS || peek() == Token::LBRACE) { | 1595 if (peek() == Token::EXTENDS || peek() == Token::LBRACE) { |
1569 // ClassDeclaration[+Default] :: | 1596 // ClassDeclaration[+Default] :: |
1570 // 'class' ('extends' LeftHandExpression)? '{' ClassBody '}' | 1597 // 'class' ('extends' LeftHandExpression)? '{' ClassBody '}' |
1571 default_export = ParseClassLiteral(nullptr, default_string, | 1598 default_export = ParseClassLiteral(nullptr, default_string, |
(...skipping 481 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2053 return factory()->NewExpressionStatement( | 2080 return factory()->NewExpressionStatement( |
2054 factory()->NewAssignment(Token::INIT, proxy, lit, RelocInfo::kNoPosition), | 2081 factory()->NewAssignment(Token::INIT, proxy, lit, RelocInfo::kNoPosition), |
2055 pos); | 2082 pos); |
2056 } | 2083 } |
2057 | 2084 |
2058 | 2085 |
2059 Statement* Parser::ParseHoistableDeclaration( | 2086 Statement* Parser::ParseHoistableDeclaration( |
2060 ZoneList<const AstRawString*>* names, bool* ok) { | 2087 ZoneList<const AstRawString*>* names, bool* ok) { |
2061 Expect(Token::FUNCTION, CHECK_OK); | 2088 Expect(Token::FUNCTION, CHECK_OK); |
2062 int pos = position(); | 2089 int pos = position(); |
2063 bool is_generator = Check(Token::MUL); | 2090 ParseFunctionFlags flags = ParseFunctionFlags::kIsNormal; |
2064 return ParseHoistableDeclaration(pos, is_generator, names, ok); | 2091 if (Check(Token::MUL)) { |
| 2092 flags |= ParseFunctionFlags::kIsGenerator; |
| 2093 } |
| 2094 return ParseHoistableDeclaration(pos, flags, names, ok); |
2065 } | 2095 } |
2066 | 2096 |
| 2097 Statement* Parser::ParseAsyncFunctionDeclaration( |
| 2098 ZoneList<const AstRawString*>* names, bool* ok) { |
| 2099 DCHECK_EQ(scanner()->current_token(), Token::IDENTIFIER); |
| 2100 DCHECK(scanner()->is_literal_contextual_keyword(CStrVector("async"))); |
| 2101 int pos = position(); |
| 2102 Expect(Token::FUNCTION, CHECK_OK); |
| 2103 ParseFunctionFlags flags = ParseFunctionFlags::kIsAsync; |
| 2104 return ParseHoistableDeclaration(pos, flags, names, ok); |
| 2105 } |
2067 | 2106 |
2068 Statement* Parser::ParseHoistableDeclaration( | 2107 Statement* Parser::ParseHoistableDeclaration( |
2069 int pos, bool is_generator, ZoneList<const AstRawString*>* names, | 2108 int pos, ParseFunctionFlags flags, ZoneList<const AstRawString*>* names, |
2070 bool* ok) { | 2109 bool* ok) { |
2071 // FunctionDeclaration :: | 2110 // FunctionDeclaration :: |
2072 // 'function' Identifier '(' FormalParameters ')' '{' FunctionBody '}' | 2111 // 'function' Identifier '(' FormalParameters ')' '{' FunctionBody '}' |
2073 // GeneratorDeclaration :: | 2112 // GeneratorDeclaration :: |
2074 // 'function' '*' Identifier '(' FormalParameters ')' '{' FunctionBody '}' | 2113 // 'function' '*' Identifier '(' FormalParameters ')' '{' FunctionBody '}' |
2075 // | 2114 // |
2076 // 'function' and '*' (if present) have been consumed by the caller. | 2115 // 'function' and '*' (if present) have been consumed by the caller. |
| 2116 const bool is_generator = flags & ParseFunctionFlags::kIsGenerator; |
| 2117 const bool is_async = flags & ParseFunctionFlags::kIsAsync; |
| 2118 DCHECK(!is_generator || !is_async); |
| 2119 |
2077 bool is_strict_reserved = false; | 2120 bool is_strict_reserved = false; |
2078 const AstRawString* name = ParseIdentifierOrStrictReservedWord( | 2121 const AstRawString* name = ParseIdentifierOrStrictReservedWord( |
2079 &is_strict_reserved, CHECK_OK); | 2122 &is_strict_reserved, CHECK_OK); |
2080 | 2123 |
| 2124 if (V8_UNLIKELY(is_async_function() && is_async && this->IsAwait(name))) { |
| 2125 ReportMessageAt(scanner()->location(), |
| 2126 MessageTemplate::kAwaitBindingIdentifier); |
| 2127 *ok = false; |
| 2128 return nullptr; |
| 2129 } |
| 2130 |
2081 FuncNameInferrer::State fni_state(fni_); | 2131 FuncNameInferrer::State fni_state(fni_); |
2082 if (fni_ != NULL) fni_->PushEnclosingName(name); | 2132 if (fni_ != NULL) fni_->PushEnclosingName(name); |
2083 FunctionLiteral* fun = ParseFunctionLiteral( | 2133 FunctionLiteral* fun = ParseFunctionLiteral( |
2084 name, scanner()->location(), | 2134 name, scanner()->location(), |
2085 is_strict_reserved ? kFunctionNameIsStrictReserved | 2135 is_strict_reserved ? kFunctionNameIsStrictReserved |
2086 : kFunctionNameValidityUnknown, | 2136 : kFunctionNameValidityUnknown, |
2087 is_generator ? FunctionKind::kGeneratorFunction | 2137 is_generator ? FunctionKind::kGeneratorFunction |
2088 : FunctionKind::kNormalFunction, | 2138 : is_async ? FunctionKind::kAsyncFunction |
| 2139 : FunctionKind::kNormalFunction, |
2089 pos, FunctionLiteral::kDeclaration, language_mode(), CHECK_OK); | 2140 pos, FunctionLiteral::kDeclaration, language_mode(), CHECK_OK); |
2090 | 2141 |
2091 // Even if we're not at the top-level of the global or a function | 2142 // Even if we're not at the top-level of the global or a function |
2092 // scope, we treat it as such and introduce the function with its | 2143 // scope, we treat it as such and introduce the function with its |
2093 // initial value upon entering the corresponding scope. | 2144 // initial value upon entering the corresponding scope. |
2094 // In ES6, a function behaves as a lexical binding, except in | 2145 // In ES6, a function behaves as a lexical binding, except in |
2095 // a script scope, or the initial scope of eval or another function. | 2146 // a script scope, or the initial scope of eval or another function. |
2096 VariableMode mode = | 2147 VariableMode mode = |
2097 (!scope_->is_declaration_scope() || scope_->is_module_scope()) ? LET | 2148 (!scope_->is_declaration_scope() || scope_->is_module_scope()) ? LET |
2098 : VAR; | 2149 : VAR; |
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2391 return true; | 2442 return true; |
2392 } | 2443 } |
2393 } | 2444 } |
2394 } | 2445 } |
2395 return false; | 2446 return false; |
2396 } | 2447 } |
2397 | 2448 |
2398 Statement* Parser::ParseFunctionDeclaration(bool* ok) { | 2449 Statement* Parser::ParseFunctionDeclaration(bool* ok) { |
2399 Consume(Token::FUNCTION); | 2450 Consume(Token::FUNCTION); |
2400 int pos = position(); | 2451 int pos = position(); |
2401 bool is_generator = Check(Token::MUL); | 2452 ParseFunctionFlags flags = ParseFunctionFlags::kIsNormal; |
2402 if (allow_harmony_restrictive_declarations() && is_generator) { | 2453 if (Check(Token::MUL)) { |
2403 ParserTraits::ReportMessageAt( | 2454 flags |= ParseFunctionFlags::kIsGenerator; |
2404 scanner()->location(), | 2455 if (allow_harmony_restrictive_declarations()) { |
2405 MessageTemplate::kGeneratorInLegacyContext); | 2456 ParserTraits::ReportMessageAt(scanner()->location(), |
2406 *ok = false; | 2457 MessageTemplate::kGeneratorInLegacyContext); |
2407 return nullptr; | 2458 *ok = false; |
| 2459 return nullptr; |
| 2460 } |
2408 } | 2461 } |
2409 return ParseHoistableDeclaration(pos, is_generator, nullptr, CHECK_OK); | 2462 |
| 2463 return ParseHoistableDeclaration(pos, flags, nullptr, CHECK_OK); |
2410 } | 2464 } |
2411 | 2465 |
2412 Statement* Parser::ParseExpressionOrLabelledStatement( | 2466 Statement* Parser::ParseExpressionOrLabelledStatement( |
2413 ZoneList<const AstRawString*>* labels, | 2467 ZoneList<const AstRawString*>* labels, |
2414 AllowLabelledFunctionStatement allow_function, bool* ok) { | 2468 AllowLabelledFunctionStatement allow_function, bool* ok) { |
2415 // ExpressionStatement | LabelledStatement :: | 2469 // ExpressionStatement | LabelledStatement :: |
2416 // Expression ';' | 2470 // Expression ';' |
2417 // Identifier ':' Statement | 2471 // Identifier ':' Statement |
2418 // | 2472 // |
2419 // ExpressionStatement[Yield] : | 2473 // ExpressionStatement[Yield] : |
(...skipping 1778 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4198 expected_property_count, arity, duplicate_parameters, function_type, | 4252 expected_property_count, arity, duplicate_parameters, function_type, |
4199 eager_compile_hint, kind, pos); | 4253 eager_compile_hint, kind, pos); |
4200 function_literal->set_function_token_position(function_token_pos); | 4254 function_literal->set_function_token_position(function_token_pos); |
4201 if (should_be_used_once_hint) | 4255 if (should_be_used_once_hint) |
4202 function_literal->set_should_be_used_once_hint(); | 4256 function_literal->set_should_be_used_once_hint(); |
4203 | 4257 |
4204 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); | 4258 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); |
4205 return function_literal; | 4259 return function_literal; |
4206 } | 4260 } |
4207 | 4261 |
| 4262 Expression* Parser::ParseAsyncFunctionExpression(bool* ok) { |
| 4263 // AsyncFunctionDeclaration :: |
| 4264 // async [no LineTerminator here] function ( FormalParameters[Await] ) |
| 4265 // { AsyncFunctionBody } |
| 4266 // |
| 4267 // async [no LineTerminator here] function BindingIdentifier[Await] |
| 4268 // ( FormalParameters[Await] ) { AsyncFunctionBody } |
| 4269 DCHECK_EQ(scanner()->current_token(), Token::IDENTIFIER); |
| 4270 DCHECK(scanner()->is_literal_contextual_keyword(CStrVector("async"))); |
| 4271 int pos = position(); |
| 4272 Expect(Token::FUNCTION, CHECK_OK); |
| 4273 bool is_strict_reserved = false; |
| 4274 const AstRawString* name = nullptr; |
| 4275 FunctionLiteral::FunctionType type = FunctionLiteral::kAnonymousExpression; |
| 4276 |
| 4277 if (peek_any_identifier()) { |
| 4278 type = FunctionLiteral::kNamedExpression; |
| 4279 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); |
| 4280 if (this->IsAwait(name)) { |
| 4281 ReportMessageAt(scanner()->location(), |
| 4282 MessageTemplate::kAwaitBindingIdentifier); |
| 4283 *ok = false; |
| 4284 return nullptr; |
| 4285 } |
| 4286 } |
| 4287 return ParseFunctionLiteral(name, scanner()->location(), |
| 4288 is_strict_reserved ? kFunctionNameIsStrictReserved |
| 4289 : kFunctionNameValidityUnknown, |
| 4290 FunctionKind::kAsyncFunction, pos, type, |
| 4291 language_mode(), CHECK_OK); |
| 4292 } |
4208 | 4293 |
4209 void Parser::SkipLazyFunctionBody(int* materialized_literal_count, | 4294 void Parser::SkipLazyFunctionBody(int* materialized_literal_count, |
4210 int* expected_property_count, bool* ok, | 4295 int* expected_property_count, bool* ok, |
4211 Scanner::BookmarkScope* bookmark) { | 4296 Scanner::BookmarkScope* bookmark) { |
4212 DCHECK_IMPLIES(bookmark, bookmark->HasBeenSet()); | 4297 DCHECK_IMPLIES(bookmark, bookmark->HasBeenSet()); |
4213 if (produce_cached_parse_data()) CHECK(log_); | 4298 if (produce_cached_parse_data()) CHECK(log_); |
4214 | 4299 |
4215 int function_block_pos = position(); | 4300 int function_block_pos = position(); |
4216 if (consume_cached_parse_data() && !cached_parse_data_->rejected()) { | 4301 if (consume_cached_parse_data() && !cached_parse_data_->rejected()) { |
4217 // If we have cached data, we use it to skip parsing the function body. The | 4302 // If we have cached data, we use it to skip parsing the function body. The |
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4597 NULL, stack_limit_); | 4682 NULL, stack_limit_); |
4598 reusable_preparser_->set_allow_lazy(true); | 4683 reusable_preparser_->set_allow_lazy(true); |
4599 #define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name()); | 4684 #define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name()); |
4600 SET_ALLOW(natives); | 4685 SET_ALLOW(natives); |
4601 SET_ALLOW(harmony_do_expressions); | 4686 SET_ALLOW(harmony_do_expressions); |
4602 SET_ALLOW(harmony_for_in); | 4687 SET_ALLOW(harmony_for_in); |
4603 SET_ALLOW(harmony_function_name); | 4688 SET_ALLOW(harmony_function_name); |
4604 SET_ALLOW(harmony_function_sent); | 4689 SET_ALLOW(harmony_function_sent); |
4605 SET_ALLOW(harmony_exponentiation_operator); | 4690 SET_ALLOW(harmony_exponentiation_operator); |
4606 SET_ALLOW(harmony_restrictive_declarations); | 4691 SET_ALLOW(harmony_restrictive_declarations); |
| 4692 SET_ALLOW(harmony_async_await); |
4607 #undef SET_ALLOW | 4693 #undef SET_ALLOW |
4608 } | 4694 } |
4609 PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction( | 4695 PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction( |
4610 language_mode(), function_state_->kind(), scope_->has_simple_parameters(), | 4696 language_mode(), function_state_->kind(), scope_->has_simple_parameters(), |
4611 parsing_module_, logger, bookmark, use_counts_); | 4697 parsing_module_, logger, bookmark, use_counts_); |
4612 if (pre_parse_timer_ != NULL) { | 4698 if (pre_parse_timer_ != NULL) { |
4613 pre_parse_timer_->Stop(); | 4699 pre_parse_timer_->Stop(); |
4614 } | 4700 } |
4615 return result; | 4701 return result; |
4616 } | 4702 } |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4667 FunctionLiteral* constructor = NULL; | 4753 FunctionLiteral* constructor = NULL; |
4668 bool has_seen_constructor = false; | 4754 bool has_seen_constructor = false; |
4669 | 4755 |
4670 Expect(Token::LBRACE, CHECK_OK); | 4756 Expect(Token::LBRACE, CHECK_OK); |
4671 | 4757 |
4672 const bool has_extends = extends != nullptr; | 4758 const bool has_extends = extends != nullptr; |
4673 while (peek() != Token::RBRACE) { | 4759 while (peek() != Token::RBRACE) { |
4674 if (Check(Token::SEMICOLON)) continue; | 4760 if (Check(Token::SEMICOLON)) continue; |
4675 FuncNameInferrer::State fni_state(fni_); | 4761 FuncNameInferrer::State fni_state(fni_); |
4676 const bool in_class = true; | 4762 const bool in_class = true; |
4677 const bool is_static = false; | |
4678 bool is_computed_name = false; // Classes do not care about computed | 4763 bool is_computed_name = false; // Classes do not care about computed |
4679 // property names here. | 4764 // property names here. |
4680 ExpressionClassifier property_classifier(this); | 4765 ExpressionClassifier property_classifier(this); |
4681 const AstRawString* property_name = nullptr; | 4766 const AstRawString* property_name = nullptr; |
4682 ObjectLiteral::Property* property = ParsePropertyDefinition( | 4767 ObjectLiteral::Property* property = ParsePropertyDefinition( |
4683 &checker, in_class, has_extends, is_static, &is_computed_name, | 4768 &checker, in_class, has_extends, MethodKind::None, &is_computed_name, |
4684 &has_seen_constructor, &property_classifier, &property_name, CHECK_OK); | 4769 &has_seen_constructor, &property_classifier, &property_name, CHECK_OK); |
4685 RewriteNonPattern(&property_classifier, CHECK_OK); | 4770 RewriteNonPattern(&property_classifier, CHECK_OK); |
4686 if (classifier != nullptr) { | 4771 if (classifier != nullptr) { |
4687 classifier->Accumulate(&property_classifier, | 4772 classifier->Accumulate(&property_classifier, |
4688 ExpressionClassifier::ExpressionProductions); | 4773 ExpressionClassifier::ExpressionProductions); |
4689 } | 4774 } |
4690 | 4775 |
4691 if (has_seen_constructor && constructor == NULL) { | 4776 if (has_seen_constructor && constructor == NULL) { |
4692 constructor = GetPropertyValue(property)->AsFunctionLiteral(); | 4777 constructor = GetPropertyValue(property)->AsFunctionLiteral(); |
4693 DCHECK_NOT_NULL(constructor); | 4778 DCHECK_NOT_NULL(constructor); |
(...skipping 610 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5304 for (int i = 0; i < tail_call_expressions.length(); ++i) { | 5389 for (int i = 0; i < tail_call_expressions.length(); ++i) { |
5305 Expression* expression = tail_call_expressions[i]; | 5390 Expression* expression = tail_call_expressions[i]; |
5306 // If only FLAG_harmony_explicit_tailcalls is enabled then expression | 5391 // If only FLAG_harmony_explicit_tailcalls is enabled then expression |
5307 // must be a Call expression. | 5392 // must be a Call expression. |
5308 DCHECK(FLAG_harmony_tailcalls || !FLAG_harmony_explicit_tailcalls || | 5393 DCHECK(FLAG_harmony_tailcalls || !FLAG_harmony_explicit_tailcalls || |
5309 expression->IsCall()); | 5394 expression->IsCall()); |
5310 MarkTailPosition(expression); | 5395 MarkTailPosition(expression); |
5311 } | 5396 } |
5312 } | 5397 } |
5313 | 5398 |
| 5399 Expression* ParserTraits::ExpressionListToExpression( |
| 5400 ZoneList<Expression*>* args) { |
| 5401 AstNodeFactory* factory = parser_->factory(); |
| 5402 Expression* expr = args->at(0); |
| 5403 for (int i = 1; i < args->length(); ++i) { |
| 5404 expr = factory->NewBinaryOperation(Token::COMMA, expr, args->at(i), |
| 5405 expr->position()); |
| 5406 } |
| 5407 return expr; |
| 5408 } |
| 5409 |
5314 void ParserTraits::RewriteDestructuringAssignments() { | 5410 void ParserTraits::RewriteDestructuringAssignments() { |
5315 parser_->RewriteDestructuringAssignments(); | 5411 parser_->RewriteDestructuringAssignments(); |
5316 } | 5412 } |
5317 | 5413 |
5318 Expression* ParserTraits::RewriteExponentiation(Expression* left, | 5414 Expression* ParserTraits::RewriteExponentiation(Expression* left, |
5319 Expression* right, int pos) { | 5415 Expression* right, int pos) { |
5320 return parser_->RewriteExponentiation(left, right, pos); | 5416 return parser_->RewriteExponentiation(left, right, pos); |
5321 } | 5417 } |
5322 | 5418 |
5323 Expression* ParserTraits::RewriteAssignExponentiation(Expression* left, | 5419 Expression* ParserTraits::RewriteAssignExponentiation(Expression* left, |
5324 Expression* right, | 5420 Expression* right, |
5325 int pos) { | 5421 int pos) { |
5326 return parser_->RewriteAssignExponentiation(left, right, pos); | 5422 return parser_->RewriteAssignExponentiation(left, right, pos); |
5327 } | 5423 } |
5328 | 5424 |
5329 void ParserTraits::RewriteNonPattern(Type::ExpressionClassifier* classifier, | 5425 void ParserTraits::RewriteNonPattern(Type::ExpressionClassifier* classifier, |
5330 bool* ok) { | 5426 bool* ok) { |
5331 parser_->RewriteNonPattern(classifier, ok); | 5427 parser_->RewriteNonPattern(classifier, ok); |
5332 } | 5428 } |
5333 | 5429 |
| 5430 Expression* ParserTraits::RewriteAwaitExpression(Expression* value, int pos) { |
| 5431 // TODO(caitp): Implement AsyncFunctionAwait() |
| 5432 // per tc39.github.io/ecmascript-asyncawait/#abstract-ops-async-function-await |
| 5433 return value; |
| 5434 } |
5334 | 5435 |
5335 Zone* ParserTraits::zone() const { | 5436 Zone* ParserTraits::zone() const { |
5336 return parser_->function_state_->scope()->zone(); | 5437 return parser_->function_state_->scope()->zone(); |
5337 } | 5438 } |
5338 | 5439 |
5339 | 5440 |
5340 ZoneList<Expression*>* ParserTraits::GetNonPatternList() const { | 5441 ZoneList<Expression*>* ParserTraits::GetNonPatternList() const { |
5341 return parser_->function_state_->non_patterns_to_rewrite(); | 5442 return parser_->function_state_->non_patterns_to_rewrite(); |
5342 } | 5443 } |
5343 | 5444 |
(...skipping 1472 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6816 try_block, target); | 6917 try_block, target); |
6817 final_loop = target; | 6918 final_loop = target; |
6818 } | 6919 } |
6819 | 6920 |
6820 return final_loop; | 6921 return final_loop; |
6821 } | 6922 } |
6822 | 6923 |
6823 | 6924 |
6824 } // namespace internal | 6925 } // namespace internal |
6825 } // namespace v8 | 6926 } // namespace v8 |
OLD | NEW |