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

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

Issue 2622833002: WIP [esnext] implement async iteration proposal (Closed)
Patch Set: simplify AsyncIteratorValueUnwrap 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
« no previous file with comments | « src/parsing/parser.cc ('k') | src/parsing/pattern-rewriter.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/parsing/parser.cc ('k') | src/parsing/pattern-rewriter.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698