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

Side by Side Diff: src/parsing/parser-base.h

Issue 2622833002: WIP [esnext] implement async iteration proposal (Closed)
Patch Set: Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698