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 #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/ast.h" | 8 #include "src/ast/ast.h" |
9 #include "src/ast/scopes.h" | 9 #include "src/ast/scopes.h" |
10 #include "src/bailout-reason.h" | 10 #include "src/bailout-reason.h" |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
211 stack_overflow_(false), | 211 stack_overflow_(false), |
212 default_eager_compile_hint_(FunctionLiteral::kShouldLazyCompile), | 212 default_eager_compile_hint_(FunctionLiteral::kShouldLazyCompile), |
213 function_literal_id_(0), | 213 function_literal_id_(0), |
214 allow_natives_(false), | 214 allow_natives_(false), |
215 allow_tailcalls_(false), | 215 allow_tailcalls_(false), |
216 allow_harmony_do_expressions_(false), | 216 allow_harmony_do_expressions_(false), |
217 allow_harmony_function_sent_(false), | 217 allow_harmony_function_sent_(false), |
218 allow_harmony_restrictive_generators_(false), | 218 allow_harmony_restrictive_generators_(false), |
219 allow_harmony_trailing_commas_(false), | 219 allow_harmony_trailing_commas_(false), |
220 allow_harmony_class_fields_(false), | 220 allow_harmony_class_fields_(false), |
221 allow_harmony_object_spread_(false) {} | 221 allow_harmony_object_spread_(false), |
| 222 allow_harmony_async_iteration_(false) {} |
222 | 223 |
223 #define ALLOW_ACCESSORS(name) \ | 224 #define ALLOW_ACCESSORS(name) \ |
224 bool allow_##name() const { return allow_##name##_; } \ | 225 bool allow_##name() const { return allow_##name##_; } \ |
225 void set_allow_##name(bool allow) { allow_##name##_ = allow; } | 226 void set_allow_##name(bool allow) { allow_##name##_ = allow; } |
226 | 227 |
227 ALLOW_ACCESSORS(natives); | 228 ALLOW_ACCESSORS(natives); |
228 ALLOW_ACCESSORS(tailcalls); | 229 ALLOW_ACCESSORS(tailcalls); |
229 ALLOW_ACCESSORS(harmony_do_expressions); | 230 ALLOW_ACCESSORS(harmony_do_expressions); |
230 ALLOW_ACCESSORS(harmony_function_sent); | 231 ALLOW_ACCESSORS(harmony_function_sent); |
231 ALLOW_ACCESSORS(harmony_restrictive_generators); | 232 ALLOW_ACCESSORS(harmony_restrictive_generators); |
232 ALLOW_ACCESSORS(harmony_trailing_commas); | 233 ALLOW_ACCESSORS(harmony_trailing_commas); |
233 ALLOW_ACCESSORS(harmony_class_fields); | 234 ALLOW_ACCESSORS(harmony_class_fields); |
234 ALLOW_ACCESSORS(harmony_object_spread); | 235 ALLOW_ACCESSORS(harmony_object_spread); |
| 236 ALLOW_ACCESSORS(harmony_async_iteration); |
235 | 237 |
236 #undef ALLOW_ACCESSORS | 238 #undef ALLOW_ACCESSORS |
237 | 239 |
238 uintptr_t stack_limit() const { return stack_limit_; } | 240 uintptr_t stack_limit() const { return stack_limit_; } |
239 | 241 |
240 void set_stack_limit(uintptr_t stack_limit) { stack_limit_ = stack_limit; } | 242 void set_stack_limit(uintptr_t stack_limit) { stack_limit_ = stack_limit; } |
241 | 243 |
242 void set_default_eager_compile_hint( | 244 void set_default_eager_compile_hint( |
243 FunctionLiteral::EagerCompileHint eager_compile_hint) { | 245 FunctionLiteral::EagerCompileHint eager_compile_hint) { |
244 default_eager_compile_hint_ = eager_compile_hint; | 246 default_eager_compile_hint_ = eager_compile_hint; |
(...skipping 690 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
935 void RaiseLanguageMode(LanguageMode mode) { | 937 void RaiseLanguageMode(LanguageMode mode) { |
936 LanguageMode old = scope()->language_mode(); | 938 LanguageMode old = scope()->language_mode(); |
937 impl()->SetLanguageMode(scope(), old > mode ? old : mode); | 939 impl()->SetLanguageMode(scope(), old > mode ? old : mode); |
938 } | 940 } |
939 bool is_generator() const { | 941 bool is_generator() const { |
940 return IsGeneratorFunction(function_state_->kind()); | 942 return IsGeneratorFunction(function_state_->kind()); |
941 } | 943 } |
942 bool is_async_function() const { | 944 bool is_async_function() const { |
943 return IsAsyncFunction(function_state_->kind()); | 945 return IsAsyncFunction(function_state_->kind()); |
944 } | 946 } |
| 947 bool is_async_generator() const { |
| 948 return IsAsyncGeneratorFunction(function_state_->kind()); |
| 949 } |
945 bool is_resumable() const { | 950 bool is_resumable() const { |
946 return IsResumableFunction(function_state_->kind()); | 951 return IsResumableFunction(function_state_->kind()); |
947 } | 952 } |
948 | 953 |
949 // Report syntax errors. | 954 // Report syntax errors. |
950 void ReportMessage(MessageTemplate::Template message) { | 955 void ReportMessage(MessageTemplate::Template message) { |
951 Scanner::Location source_location = scanner()->location(); | 956 Scanner::Location source_location = scanner()->location(); |
952 impl()->ReportMessageAt(source_location, message, | 957 impl()->ReportMessageAt(source_location, message, |
953 static_cast<const char*>(nullptr), kSyntaxError); | 958 static_cast<const char*>(nullptr), kSyntaxError); |
954 } | 959 } |
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1282 bool* ok); | 1287 bool* ok); |
1283 StatementT ParseDoWhileStatement(ZoneList<const AstRawString*>* labels, | 1288 StatementT ParseDoWhileStatement(ZoneList<const AstRawString*>* labels, |
1284 bool* ok); | 1289 bool* ok); |
1285 StatementT ParseWhileStatement(ZoneList<const AstRawString*>* labels, | 1290 StatementT ParseWhileStatement(ZoneList<const AstRawString*>* labels, |
1286 bool* ok); | 1291 bool* ok); |
1287 StatementT ParseThrowStatement(bool* ok); | 1292 StatementT ParseThrowStatement(bool* ok); |
1288 StatementT ParseSwitchStatement(ZoneList<const AstRawString*>* labels, | 1293 StatementT ParseSwitchStatement(ZoneList<const AstRawString*>* labels, |
1289 bool* ok); | 1294 bool* ok); |
1290 StatementT ParseTryStatement(bool* ok); | 1295 StatementT ParseTryStatement(bool* ok); |
1291 StatementT ParseForStatement(ZoneList<const AstRawString*>* labels, bool* ok); | 1296 StatementT ParseForStatement(ZoneList<const AstRawString*>* labels, bool* ok); |
| 1297 StatementT ParseForAwaitStatement(ZoneList<const AstRawString*>* labels, |
| 1298 bool* ok); |
| 1299 V8_INLINE StatementT ParseForStatementOrForAwaitStatement( |
| 1300 ZoneList<const AstRawString*>* labels, bool* ok) { |
| 1301 if (V8_UNLIKELY(allow_harmony_async_iteration() && is_async_function() && |
| 1302 PeekAhead() == Token::AWAIT)) { |
| 1303 return ParseForAwaitStatement(labels, ok); |
| 1304 } |
| 1305 return ParseForStatement(labels, ok); |
| 1306 } |
1292 | 1307 |
1293 bool IsNextLetKeyword(); | 1308 bool IsNextLetKeyword(); |
1294 bool IsTrivialExpression(); | 1309 bool IsTrivialExpression(); |
1295 | 1310 |
1296 // Checks if the expression is a valid reference expression (e.g., on the | 1311 // Checks if the expression is a valid reference expression (e.g., on the |
1297 // left-hand side of assignments). Although ruled out by ECMA as early errors, | 1312 // left-hand side of assignments). Although ruled out by ECMA as early errors, |
1298 // we allow calls for web compatibility and rewrite them to a runtime throw. | 1313 // we allow calls for web compatibility and rewrite them to a runtime throw. |
1299 ExpressionT CheckAndRewriteReferenceExpression( | 1314 ExpressionT CheckAndRewriteReferenceExpression( |
1300 ExpressionT expression, int beg_pos, int end_pos, | 1315 ExpressionT expression, int beg_pos, int end_pos, |
1301 MessageTemplate::Template message, bool* ok); | 1316 MessageTemplate::Template message, bool* ok); |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1450 int function_literal_id_; | 1465 int function_literal_id_; |
1451 | 1466 |
1452 bool allow_natives_; | 1467 bool allow_natives_; |
1453 bool allow_tailcalls_; | 1468 bool allow_tailcalls_; |
1454 bool allow_harmony_do_expressions_; | 1469 bool allow_harmony_do_expressions_; |
1455 bool allow_harmony_function_sent_; | 1470 bool allow_harmony_function_sent_; |
1456 bool allow_harmony_restrictive_generators_; | 1471 bool allow_harmony_restrictive_generators_; |
1457 bool allow_harmony_trailing_commas_; | 1472 bool allow_harmony_trailing_commas_; |
1458 bool allow_harmony_class_fields_; | 1473 bool allow_harmony_class_fields_; |
1459 bool allow_harmony_object_spread_; | 1474 bool allow_harmony_object_spread_; |
| 1475 bool allow_harmony_async_iteration_; |
1460 | 1476 |
1461 friend class DiscardableZoneScope; | 1477 friend class DiscardableZoneScope; |
1462 }; | 1478 }; |
1463 | 1479 |
1464 template <typename Impl> | 1480 template <typename Impl> |
1465 ParserBase<Impl>::FunctionState::FunctionState( | 1481 ParserBase<Impl>::FunctionState::FunctionState( |
1466 FunctionState** function_state_stack, ScopeState** scope_stack, | 1482 FunctionState** function_state_stack, ScopeState** scope_stack, |
1467 DeclarationScope* scope) | 1483 DeclarationScope* scope) |
1468 : ScopeState(scope_stack, scope), | 1484 : ScopeState(scope_stack, scope), |
1469 next_materialized_literal_index_(0), | 1485 next_materialized_literal_index_(0), |
(...skipping 570 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2040 *kind = PropertyKind::kMethodProperty; | 2056 *kind = PropertyKind::kMethodProperty; |
2041 } | 2057 } |
2042 | 2058 |
2043 Token::Value token = peek(); | 2059 Token::Value token = peek(); |
2044 int pos = peek_position(); | 2060 int pos = peek_position(); |
2045 | 2061 |
2046 if (!*is_generator && token == Token::ASYNC && | 2062 if (!*is_generator && token == Token::ASYNC && |
2047 !scanner()->HasAnyLineTerminatorAfterNext()) { | 2063 !scanner()->HasAnyLineTerminatorAfterNext()) { |
2048 Consume(Token::ASYNC); | 2064 Consume(Token::ASYNC); |
2049 token = peek(); | 2065 token = peek(); |
2050 if (SetPropertyKindFromToken(token, kind)) { | 2066 if (token == Token::MUL && allow_harmony_async_iteration() && |
| 2067 !scanner()->HasAnyLineTerminatorBeforeNext()) { |
| 2068 Consume(Token::MUL); |
| 2069 token = peek(); |
| 2070 *is_generator = true; |
| 2071 } else if (SetPropertyKindFromToken(token, kind)) { |
2051 *name = impl()->GetSymbol(); // TODO(bakkot) specialize on 'async' | 2072 *name = impl()->GetSymbol(); // TODO(bakkot) specialize on 'async' |
2052 impl()->PushLiteralName(*name); | 2073 impl()->PushLiteralName(*name); |
2053 return factory()->NewStringLiteral(*name, pos); | 2074 return factory()->NewStringLiteral(*name, pos); |
2054 } | 2075 } |
2055 *kind = PropertyKind::kMethodProperty; | 2076 *kind = PropertyKind::kMethodProperty; |
2056 *is_async = true; | 2077 *is_async = true; |
2057 pos = peek_position(); | 2078 pos = peek_position(); |
2058 } | 2079 } |
2059 | 2080 |
2060 if (token == Token::IDENTIFIER && !*is_generator && !*is_async) { | 2081 if (token == Token::IDENTIFIER && !*is_generator && !*is_async) { |
(...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2447 return factory()->NewObjectLiteralProperty( | 2468 return factory()->NewObjectLiteralProperty( |
2448 name_expression, value, ObjectLiteralProperty::COMPUTED, false); | 2469 name_expression, value, ObjectLiteralProperty::COMPUTED, false); |
2449 } | 2470 } |
2450 | 2471 |
2451 case PropertyKind::kMethodProperty: { | 2472 case PropertyKind::kMethodProperty: { |
2452 DCHECK(!is_get && !is_set); | 2473 DCHECK(!is_get && !is_set); |
2453 | 2474 |
2454 // MethodDefinition | 2475 // MethodDefinition |
2455 // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' | 2476 // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' |
2456 // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' | 2477 // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' |
| 2478 // async PropertyName '(' StrictFormalParameters ')' |
| 2479 // '{' FunctionBody '}' |
| 2480 // async '*' PropertyName '(' StrictFormalParameters ')' |
| 2481 // '{' FunctionBody '}' |
2457 | 2482 |
2458 classifier()->RecordPatternError( | 2483 classifier()->RecordPatternError( |
2459 Scanner::Location(next_beg_pos, scanner()->location().end_pos), | 2484 Scanner::Location(next_beg_pos, scanner()->location().end_pos), |
2460 MessageTemplate::kInvalidDestructuringTarget); | 2485 MessageTemplate::kInvalidDestructuringTarget); |
2461 | 2486 |
2462 FunctionKind kind = is_generator | 2487 static const FunctionKind kMethodKinds[] = { |
2463 ? FunctionKind::kConciseGeneratorMethod | 2488 FunctionKind::kConciseMethod, FunctionKind::kConciseGeneratorMethod, |
2464 : is_async ? FunctionKind::kAsyncConciseMethod | 2489 FunctionKind::kAsyncConciseMethod, |
2465 : FunctionKind::kConciseMethod; | 2490 FunctionKind::kAsyncConciseGeneratorMethod}; |
| 2491 int index = static_cast<int>(!!is_generator) + |
| 2492 (static_cast<int>(!!is_async) << 1); |
| 2493 FunctionKind kind = kMethodKinds[index]; |
2466 | 2494 |
2467 ExpressionT value = impl()->ParseFunctionLiteral( | 2495 ExpressionT value = impl()->ParseFunctionLiteral( |
2468 name, scanner()->location(), kSkipFunctionNameCheck, kind, | 2496 name, scanner()->location(), kSkipFunctionNameCheck, kind, |
2469 kNoSourcePosition, FunctionLiteral::kAccessorOrMethod, | 2497 kNoSourcePosition, FunctionLiteral::kAccessorOrMethod, |
2470 language_mode(), CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2498 language_mode(), CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2471 | 2499 |
2472 return factory()->NewObjectLiteralProperty( | 2500 return factory()->NewObjectLiteralProperty( |
2473 name_expression, value, ObjectLiteralProperty::COMPUTED, | 2501 name_expression, value, ObjectLiteralProperty::COMPUTED, |
2474 *is_computed_name); | 2502 *is_computed_name); |
2475 } | 2503 } |
(...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2881 expression = ParseAssignmentExpression(accept_IN, CHECK_OK); | 2909 expression = ParseAssignmentExpression(accept_IN, CHECK_OK); |
2882 impl()->RewriteNonPattern(CHECK_OK); | 2910 impl()->RewriteNonPattern(CHECK_OK); |
2883 break; | 2911 break; |
2884 } | 2912 } |
2885 } | 2913 } |
2886 | 2914 |
2887 if (delegating) { | 2915 if (delegating) { |
2888 return impl()->RewriteYieldStar(generator_object, expression, pos); | 2916 return impl()->RewriteYieldStar(generator_object, expression, pos); |
2889 } | 2917 } |
2890 | 2918 |
2891 expression = impl()->BuildIteratorResult(expression, false); | 2919 if (!is_async_generator()) { |
| 2920 // Async generator yield is rewritten in Ignition, and doesn't require |
| 2921 // producing an Iterator Result. |
| 2922 expression = impl()->BuildIteratorResult(expression, false); |
| 2923 } |
| 2924 |
2892 // Hackily disambiguate o from o.next and o [Symbol.iterator](). | 2925 // Hackily disambiguate o from o.next and o [Symbol.iterator](). |
2893 // TODO(verwaest): Come up with a better solution. | 2926 // TODO(verwaest): Come up with a better solution. |
2894 ExpressionT yield = factory()->NewYield(generator_object, expression, pos, | 2927 ExpressionT yield = factory()->NewYield(generator_object, expression, pos, |
2895 Yield::kOnExceptionThrow); | 2928 Yield::kOnExceptionThrow); |
2896 return yield; | 2929 return yield; |
2897 } | 2930 } |
2898 | 2931 |
2899 // Precedence = 3 | 2932 // Precedence = 3 |
2900 template <typename Impl> | 2933 template <typename Impl> |
2901 typename ParserBase<Impl>::ExpressionT | 2934 typename ParserBase<Impl>::ExpressionT |
(...skipping 842 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3744 // 'function' Identifier '(' FormalParameters ')' '{' FunctionBody '}' | 3777 // 'function' Identifier '(' FormalParameters ')' '{' FunctionBody '}' |
3745 // 'function' '(' FormalParameters ')' '{' FunctionBody '}' | 3778 // 'function' '(' FormalParameters ')' '{' FunctionBody '}' |
3746 // GeneratorDeclaration :: | 3779 // GeneratorDeclaration :: |
3747 // 'function' '*' Identifier '(' FormalParameters ')' '{' FunctionBody '}' | 3780 // 'function' '*' Identifier '(' FormalParameters ')' '{' FunctionBody '}' |
3748 // 'function' '*' '(' FormalParameters ')' '{' FunctionBody '}' | 3781 // 'function' '*' '(' FormalParameters ')' '{' FunctionBody '}' |
3749 // | 3782 // |
3750 // The anonymous forms are allowed iff [default_export] is true. | 3783 // The anonymous forms are allowed iff [default_export] is true. |
3751 // | 3784 // |
3752 // 'function' and '*' (if present) have been consumed by the caller. | 3785 // 'function' and '*' (if present) have been consumed by the caller. |
3753 | 3786 |
3754 const bool is_generator = flags & ParseFunctionFlags::kIsGenerator; | 3787 bool is_generator = flags & ParseFunctionFlags::kIsGenerator; |
3755 const bool is_async = flags & ParseFunctionFlags::kIsAsync; | 3788 const bool is_async = flags & ParseFunctionFlags::kIsAsync; |
3756 DCHECK(!is_generator || !is_async); | 3789 DCHECK(!is_generator || !is_async); |
3757 | 3790 |
| 3791 if (allow_harmony_async_iteration() && is_async && Check(Token::MUL)) { |
| 3792 // Async generator |
| 3793 is_generator = true; |
| 3794 } |
| 3795 |
3758 IdentifierT name; | 3796 IdentifierT name; |
3759 FunctionNameValidity name_validity; | 3797 FunctionNameValidity name_validity; |
3760 IdentifierT variable_name; | 3798 IdentifierT variable_name; |
3761 if (default_export && peek() == Token::LPAREN) { | 3799 if (default_export && peek() == Token::LPAREN) { |
3762 impl()->GetDefaultStrings(&name, &variable_name); | 3800 impl()->GetDefaultStrings(&name, &variable_name); |
3763 name_validity = kSkipFunctionNameCheck; | 3801 name_validity = kSkipFunctionNameCheck; |
3764 } else { | 3802 } else { |
3765 bool is_strict_reserved; | 3803 bool is_strict_reserved; |
3766 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved, | 3804 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved, |
3767 CHECK_OK_CUSTOM(NullStatement)); | 3805 CHECK_OK_CUSTOM(NullStatement)); |
3768 name_validity = is_strict_reserved ? kFunctionNameIsStrictReserved | 3806 name_validity = is_strict_reserved ? kFunctionNameIsStrictReserved |
3769 : kFunctionNameValidityUnknown; | 3807 : kFunctionNameValidityUnknown; |
3770 variable_name = name; | 3808 variable_name = name; |
3771 } | 3809 } |
3772 | 3810 |
3773 FuncNameInferrer::State fni_state(fni_); | 3811 FuncNameInferrer::State fni_state(fni_); |
3774 impl()->PushEnclosingName(name); | 3812 impl()->PushEnclosingName(name); |
| 3813 |
| 3814 static const FunctionKind kFunctionKinds[] = { |
| 3815 FunctionKind::kNormalFunction, FunctionKind::kGeneratorFunction, |
| 3816 FunctionKind::kAsyncFunction, FunctionKind::kAsyncGeneratorFunction}; |
| 3817 int index = |
| 3818 static_cast<int>(!!is_generator) + (static_cast<int>(!!is_async) << 1); |
| 3819 FunctionKind kind = kFunctionKinds[index]; |
| 3820 |
3775 FunctionLiteralT function = impl()->ParseFunctionLiteral( | 3821 FunctionLiteralT function = impl()->ParseFunctionLiteral( |
3776 name, scanner()->location(), name_validity, | 3822 name, scanner()->location(), name_validity, kind, pos, |
3777 is_generator ? FunctionKind::kGeneratorFunction | 3823 FunctionLiteral::kDeclaration, language_mode(), |
3778 : is_async ? FunctionKind::kAsyncFunction | |
3779 : FunctionKind::kNormalFunction, | |
3780 pos, FunctionLiteral::kDeclaration, language_mode(), | |
3781 CHECK_OK_CUSTOM(NullStatement)); | 3824 CHECK_OK_CUSTOM(NullStatement)); |
3782 | 3825 |
3783 return impl()->DeclareFunction(variable_name, function, pos, is_generator, | 3826 return impl()->DeclareFunction(variable_name, function, pos, is_generator, |
3784 is_async, names, ok); | 3827 is_async, names, ok); |
3785 } | 3828 } |
3786 | 3829 |
3787 template <typename Impl> | 3830 template <typename Impl> |
3788 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseClassDeclaration( | 3831 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseClassDeclaration( |
3789 ZoneList<const AstRawString*>* names, bool default_export, bool* ok) { | 3832 ZoneList<const AstRawString*>* names, bool default_export, bool* ok) { |
3790 // ClassDeclaration :: | 3833 // ClassDeclaration :: |
(...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4224 // | 4267 // |
4225 // async [no LineTerminator here] function BindingIdentifier[Await] | 4268 // async [no LineTerminator here] function BindingIdentifier[Await] |
4226 // ( FormalParameters[Await] ) { AsyncFunctionBody } | 4269 // ( FormalParameters[Await] ) { AsyncFunctionBody } |
4227 DCHECK_EQ(scanner()->current_token(), Token::ASYNC); | 4270 DCHECK_EQ(scanner()->current_token(), Token::ASYNC); |
4228 int pos = position(); | 4271 int pos = position(); |
4229 Expect(Token::FUNCTION, CHECK_OK); | 4272 Expect(Token::FUNCTION, CHECK_OK); |
4230 bool is_strict_reserved = false; | 4273 bool is_strict_reserved = false; |
4231 IdentifierT name = impl()->EmptyIdentifier(); | 4274 IdentifierT name = impl()->EmptyIdentifier(); |
4232 FunctionLiteral::FunctionType type = FunctionLiteral::kAnonymousExpression; | 4275 FunctionLiteral::FunctionType type = FunctionLiteral::kAnonymousExpression; |
4233 | 4276 |
| 4277 bool is_generator = allow_harmony_async_iteration() && Check(Token::MUL); |
| 4278 |
| 4279 static const FunctionKind kFunctionKinds[] = { |
| 4280 FunctionKind::kAsyncFunction, FunctionKind::kAsyncGeneratorFunction, |
| 4281 }; |
| 4282 FunctionKind kind = kFunctionKinds[!!is_generator]; |
| 4283 |
4234 if (peek_any_identifier()) { | 4284 if (peek_any_identifier()) { |
4235 type = FunctionLiteral::kNamedExpression; | 4285 type = FunctionLiteral::kNamedExpression; |
4236 name = ParseIdentifierOrStrictReservedWord(FunctionKind::kAsyncFunction, | 4286 name = ParseIdentifierOrStrictReservedWord(kind, &is_strict_reserved, |
4237 &is_strict_reserved, CHECK_OK); | 4287 CHECK_OK); |
4238 } | 4288 } |
4239 return impl()->ParseFunctionLiteral( | 4289 return impl()->ParseFunctionLiteral( |
4240 name, scanner()->location(), | 4290 name, scanner()->location(), |
4241 is_strict_reserved ? kFunctionNameIsStrictReserved | 4291 is_strict_reserved ? kFunctionNameIsStrictReserved |
4242 : kFunctionNameValidityUnknown, | 4292 : kFunctionNameValidityUnknown, |
4243 FunctionKind::kAsyncFunction, pos, type, language_mode(), CHECK_OK); | 4293 kind, pos, type, language_mode(), CHECK_OK); |
4244 } | 4294 } |
4245 | 4295 |
4246 template <typename Impl> | 4296 template <typename Impl> |
4247 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseTemplateLiteral( | 4297 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseTemplateLiteral( |
4248 ExpressionT tag, int start, bool* ok) { | 4298 ExpressionT tag, int start, bool* ok) { |
4249 // A TemplateLiteral is made up of 0 or more TEMPLATE_SPAN tokens (literal | 4299 // A TemplateLiteral is made up of 0 or more TEMPLATE_SPAN tokens (literal |
4250 // text followed by a substitution expression), finalized by a single | 4300 // text followed by a substitution expression), finalized by a single |
4251 // TEMPLATE_TAIL. | 4301 // TEMPLATE_TAIL. |
4252 // | 4302 // |
4253 // In terms of draft language, TEMPLATE_SPAN may be either the TemplateHead or | 4303 // In terms of draft language, TEMPLATE_SPAN may be either the TemplateHead or |
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4594 case Token::SEMICOLON: | 4644 case Token::SEMICOLON: |
4595 Next(); | 4645 Next(); |
4596 return factory()->NewEmptyStatement(kNoSourcePosition); | 4646 return factory()->NewEmptyStatement(kNoSourcePosition); |
4597 case Token::IF: | 4647 case Token::IF: |
4598 return ParseIfStatement(labels, ok); | 4648 return ParseIfStatement(labels, ok); |
4599 case Token::DO: | 4649 case Token::DO: |
4600 return ParseDoWhileStatement(labels, ok); | 4650 return ParseDoWhileStatement(labels, ok); |
4601 case Token::WHILE: | 4651 case Token::WHILE: |
4602 return ParseWhileStatement(labels, ok); | 4652 return ParseWhileStatement(labels, ok); |
4603 case Token::FOR: | 4653 case Token::FOR: |
4604 return ParseForStatement(labels, ok); | 4654 return ParseForStatementOrForAwaitStatement(labels, ok); |
4605 case Token::CONTINUE: | 4655 case Token::CONTINUE: |
4606 case Token::BREAK: | 4656 case Token::BREAK: |
4607 case Token::RETURN: | 4657 case Token::RETURN: |
4608 case Token::THROW: | 4658 case Token::THROW: |
4609 case Token::TRY: { | 4659 case Token::TRY: { |
4610 // These statements must have their labels preserved in an enclosing | 4660 // These statements must have their labels preserved in an enclosing |
4611 // block, as the corresponding AST nodes do not currently store their | 4661 // block, as the corresponding AST nodes do not currently store their |
4612 // labels. | 4662 // labels. |
4613 // TODO(nikolaos, marja): Consider adding the labels to the AST nodes. | 4663 // TODO(nikolaos, marja): Consider adding the labels to the AST nodes. |
4614 if (labels == nullptr) { | 4664 if (labels == nullptr) { |
(...skipping 856 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5471 block->set_scope(for_scope); | 5521 block->set_scope(for_scope); |
5472 loop->Initialize(init, cond, next, body); | 5522 loop->Initialize(init, cond, next, body); |
5473 return block; | 5523 return block; |
5474 } else { | 5524 } else { |
5475 loop->Initialize(init, cond, next, body); | 5525 loop->Initialize(init, cond, next, body); |
5476 return loop; | 5526 return loop; |
5477 } | 5527 } |
5478 } | 5528 } |
5479 } | 5529 } |
5480 | 5530 |
| 5531 template <typename Impl> |
| 5532 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseForAwaitStatement( |
| 5533 ZoneList<const AstRawString*>* labels, bool* ok) { |
| 5534 // for await '(' ForDeclaration of AssignmentExpression ')' Statement |
| 5535 DCHECK(is_async_function()); |
| 5536 |
| 5537 int stmt_pos = peek_position(); |
| 5538 bool bound_names_are_lexical = false; |
| 5539 |
| 5540 ForInfo for_info(this); |
| 5541 BlockState for_state(zone(), &scope_state_); |
| 5542 |
| 5543 Expect(Token::FOR, CHECK_OK); |
| 5544 Expect(Token::AWAIT, CHECK_OK); |
| 5545 Expect(Token::LPAREN, CHECK_OK); |
| 5546 |
| 5547 /* |
| 5548 ZoneList<const AstRawString*> bound_names; |
| 5549 ForEachStatement::VisitMode mode; |
| 5550 int position; |
| 5551 DeclarationParsingResult parsing_result; |
| 5552 */ |
| 5553 for_info.mode = ForEachStatement::ASYNC_ITERATE; |
| 5554 for_state.set_start_position(scanner()->location().beg_pos); |
| 5555 for_state.set_is_hidden(); |
| 5556 |
| 5557 StatementT init = impl()->NullStatement(); |
| 5558 |
| 5559 bool has_declarations = false; |
| 5560 bool is_destructuring = false; |
| 5561 |
| 5562 if (peek() == Token::VAR || peek() == Token::CONST || |
| 5563 (peek() == Token::LET && IsNextLetKeyword())) { |
| 5564 // The initializer contains declarations. |
| 5565 has_declarations = true; |
| 5566 ParseVariableDeclarations(kForStatement, &for_info.parsing_result, nullptr, |
| 5567 CHECK_OK); |
| 5568 bound_names_are_lexical = |
| 5569 IsLexicalVariableMode(for_info.parsing_result.descriptor.mode); |
| 5570 for_info.position = scanner()->location().beg_pos; |
| 5571 |
| 5572 // Just one declaration followed by in/of. |
| 5573 if (for_info.parsing_result.declarations.length() != 1) { |
| 5574 impl()->ReportMessageAt(for_info.parsing_result.bindings_loc, |
| 5575 MessageTemplate::kForInOfLoopMultiBindings, |
| 5576 ForEachStatement::VisitModeString(for_info.mode)); |
| 5577 *ok = false; |
| 5578 return impl()->NullStatement(); |
| 5579 } |
| 5580 } else { |
| 5581 // The initializer does not contain declarations. |
| 5582 int lhs_beg_pos = peek_position(); |
| 5583 ExpressionClassifier classifier(this); |
| 5584 ExpressionT expression = ParseExpressionCoverGrammar(false, CHECK_OK); |
| 5585 int lhs_end_pos = scanner()->location().end_pos; |
| 5586 |
| 5587 if (expression->IsArrayLiteral() || expression->IsObjectLiteral()) { |
| 5588 ValidateAssignmentPattern(CHECK_OK); |
| 5589 } else { |
| 5590 impl()->RewriteNonPattern(CHECK_OK); |
| 5591 expression = impl()->CheckAndRewriteReferenceExpression( |
| 5592 expression, lhs_beg_pos, lhs_end_pos, |
| 5593 MessageTemplate::kInvalidLhsInFor, kSyntaxError, CHECK_OK); |
| 5594 } |
| 5595 } |
| 5596 |
| 5597 ExpectContextualKeyword(CStrVector("of"), CHECK_OK); |
| 5598 int each_keyword_pos = scanner()->location().beg_pos; |
| 5599 |
| 5600 ExpressionClassifier classifier(this); |
| 5601 ExpressionT iterable = ParseAssignmentExpression(true, CHECK_OK); |
| 5602 impl()->RewriteNonPattern(CHECK_OK); |
| 5603 |
| 5604 BlockT init_block = impl()->RewriteForVarInLegacy(for_info); |
| 5605 |
| 5606 auto loop = factory()->NewForEachStatement(for_info.mode, labels, stmt_pos); |
| 5607 typename Types::Target target(this, loop); |
| 5608 |
| 5609 Expect(Token::RPAREN, CHECK_OK); |
| 5610 |
| 5611 StatementT final_loop = impl()->NullStatement(); |
| 5612 { |
| 5613 ReturnExprScope no_tail_calls(function_state_, |
| 5614 ReturnExprContext::kInsideForInOfBody); |
| 5615 BlockState block_state(zone(), &scope_state_); |
| 5616 block_state.set_start_position(scanner()->location().beg_pos); |
| 5617 |
| 5618 StatementT body = ParseScopedStatement(nullptr, true, CHECK_OK); |
| 5619 |
| 5620 BlockT body_block = impl()->NullBlock(); |
| 5621 ExpressionT each_variable = impl()->EmptyExpression(); |
| 5622 impl()->DesugarBindingInForEachStatement(&for_info, &body_block, |
| 5623 &each_variable, CHECK_OK); |
| 5624 body_block->statements()->Add(body, zone()); |
| 5625 final_loop = impl()->InitializeForAwaitOfStatement( |
| 5626 loop, each_variable, iterable, body_block, each_keyword_pos); |
| 5627 |
| 5628 block_state.set_end_position(scanner()->location().end_pos); |
| 5629 body_block->set_scope(block_state.FinalizedBlockScope()); |
| 5630 } |
| 5631 |
| 5632 init_block = impl()->CreateForEachStatementTDZ(init_block, for_info, ok); |
| 5633 |
| 5634 for_state.set_end_position(scanner()->location().end_pos); |
| 5635 Scope* for_scope = for_state.FinalizedBlockScope(); |
| 5636 // Parsed for-in loop w/ variable declarations. |
| 5637 if (!impl()->IsNullStatement(init_block)) { |
| 5638 init_block->statements()->Add(final_loop, zone()); |
| 5639 init_block->set_scope(for_scope); |
| 5640 return init_block; |
| 5641 } |
| 5642 |
| 5643 DCHECK_NULL(for_scope); |
| 5644 return final_loop; |
| 5645 } |
| 5646 |
5481 #undef CHECK_OK | 5647 #undef CHECK_OK |
5482 #undef CHECK_OK_CUSTOM | 5648 #undef CHECK_OK_CUSTOM |
5483 | 5649 |
5484 template <typename Impl> | 5650 template <typename Impl> |
5485 void ParserBase<Impl>::ObjectLiteralChecker::CheckDuplicateProto( | 5651 void ParserBase<Impl>::ObjectLiteralChecker::CheckDuplicateProto( |
5486 Token::Value property) { | 5652 Token::Value property) { |
5487 if (property == Token::SMI || property == Token::NUMBER) return; | 5653 if (property == Token::SMI || property == Token::NUMBER) return; |
5488 | 5654 |
5489 if (IsProto()) { | 5655 if (IsProto()) { |
5490 if (has_seen_proto_) { | 5656 if (has_seen_proto_) { |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5529 has_seen_constructor_ = true; | 5695 has_seen_constructor_ = true; |
5530 return; | 5696 return; |
5531 } | 5697 } |
5532 } | 5698 } |
5533 | 5699 |
5534 | 5700 |
5535 } // namespace internal | 5701 } // namespace internal |
5536 } // namespace v8 | 5702 } // namespace v8 |
5537 | 5703 |
5538 #endif // V8_PARSING_PARSER_BASE_H | 5704 #endif // V8_PARSING_PARSER_BASE_H |
OLD | NEW |