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