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

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

Issue 2637403008: [async-iteration] add support for for-await-of loops in Async Functions (Closed)
Patch Set: [async-iteration] add support for for-await-of loops in Async Functions 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 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 stack_overflow_(false), 217 stack_overflow_(false),
218 default_eager_compile_hint_(FunctionLiteral::kShouldLazyCompile), 218 default_eager_compile_hint_(FunctionLiteral::kShouldLazyCompile),
219 function_literal_id_(0), 219 function_literal_id_(0),
220 allow_natives_(false), 220 allow_natives_(false),
221 allow_tailcalls_(false), 221 allow_tailcalls_(false),
222 allow_harmony_do_expressions_(false), 222 allow_harmony_do_expressions_(false),
223 allow_harmony_function_sent_(false), 223 allow_harmony_function_sent_(false),
224 allow_harmony_restrictive_generators_(false), 224 allow_harmony_restrictive_generators_(false),
225 allow_harmony_trailing_commas_(false), 225 allow_harmony_trailing_commas_(false),
226 allow_harmony_class_fields_(false), 226 allow_harmony_class_fields_(false),
227 allow_harmony_object_rest_spread_(false) {} 227 allow_harmony_object_rest_spread_(false),
228 allow_harmony_async_iteration_(false) {}
228 229
229 #define ALLOW_ACCESSORS(name) \ 230 #define ALLOW_ACCESSORS(name) \
230 bool allow_##name() const { return allow_##name##_; } \ 231 bool allow_##name() const { return allow_##name##_; } \
231 void set_allow_##name(bool allow) { allow_##name##_ = allow; } 232 void set_allow_##name(bool allow) { allow_##name##_ = allow; }
232 233
233 ALLOW_ACCESSORS(natives); 234 ALLOW_ACCESSORS(natives);
234 ALLOW_ACCESSORS(tailcalls); 235 ALLOW_ACCESSORS(tailcalls);
235 ALLOW_ACCESSORS(harmony_do_expressions); 236 ALLOW_ACCESSORS(harmony_do_expressions);
236 ALLOW_ACCESSORS(harmony_function_sent); 237 ALLOW_ACCESSORS(harmony_function_sent);
237 ALLOW_ACCESSORS(harmony_restrictive_generators); 238 ALLOW_ACCESSORS(harmony_restrictive_generators);
238 ALLOW_ACCESSORS(harmony_trailing_commas); 239 ALLOW_ACCESSORS(harmony_trailing_commas);
239 ALLOW_ACCESSORS(harmony_class_fields); 240 ALLOW_ACCESSORS(harmony_class_fields);
240 ALLOW_ACCESSORS(harmony_object_rest_spread); 241 ALLOW_ACCESSORS(harmony_object_rest_spread);
242 ALLOW_ACCESSORS(harmony_async_iteration);
241 243
242 #undef ALLOW_ACCESSORS 244 #undef ALLOW_ACCESSORS
243 245
244 uintptr_t stack_limit() const { return stack_limit_; } 246 uintptr_t stack_limit() const { return stack_limit_; }
245 247
246 void set_stack_limit(uintptr_t stack_limit) { stack_limit_ = stack_limit; } 248 void set_stack_limit(uintptr_t stack_limit) { stack_limit_ = stack_limit; }
247 249
248 void set_default_eager_compile_hint( 250 void set_default_eager_compile_hint(
249 FunctionLiteral::EagerCompileHint eager_compile_hint) { 251 FunctionLiteral::EagerCompileHint eager_compile_hint) {
250 default_eager_compile_hint_ = eager_compile_hint; 252 default_eager_compile_hint_ = eager_compile_hint;
(...skipping 1044 matching lines...) Expand 10 before | Expand all | Expand 10 after
1295 bool* ok); 1297 bool* ok);
1296 StatementT ParseDoWhileStatement(ZoneList<const AstRawString*>* labels, 1298 StatementT ParseDoWhileStatement(ZoneList<const AstRawString*>* labels,
1297 bool* ok); 1299 bool* ok);
1298 StatementT ParseWhileStatement(ZoneList<const AstRawString*>* labels, 1300 StatementT ParseWhileStatement(ZoneList<const AstRawString*>* labels,
1299 bool* ok); 1301 bool* ok);
1300 StatementT ParseThrowStatement(bool* ok); 1302 StatementT ParseThrowStatement(bool* ok);
1301 StatementT ParseSwitchStatement(ZoneList<const AstRawString*>* labels, 1303 StatementT ParseSwitchStatement(ZoneList<const AstRawString*>* labels,
1302 bool* ok); 1304 bool* ok);
1303 StatementT ParseTryStatement(bool* ok); 1305 StatementT ParseTryStatement(bool* ok);
1304 StatementT ParseForStatement(ZoneList<const AstRawString*>* labels, bool* ok); 1306 StatementT ParseForStatement(ZoneList<const AstRawString*>* labels, bool* ok);
1307 StatementT ParseForAwaitStatement(ZoneList<const AstRawString*>* labels,
1308 bool* ok);
1305 1309
1306 bool IsNextLetKeyword(); 1310 bool IsNextLetKeyword();
1307 bool IsTrivialExpression(); 1311 bool IsTrivialExpression();
1308 1312
1309 // 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
1310 // 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,
1311 // 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.
1312 ExpressionT CheckAndRewriteReferenceExpression( 1316 ExpressionT CheckAndRewriteReferenceExpression(
1313 ExpressionT expression, int beg_pos, int end_pos, 1317 ExpressionT expression, int beg_pos, int end_pos,
1314 MessageTemplate::Template message, bool* ok); 1318 MessageTemplate::Template message, bool* ok);
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
1463 int function_literal_id_; 1467 int function_literal_id_;
1464 1468
1465 bool allow_natives_; 1469 bool allow_natives_;
1466 bool allow_tailcalls_; 1470 bool allow_tailcalls_;
1467 bool allow_harmony_do_expressions_; 1471 bool allow_harmony_do_expressions_;
1468 bool allow_harmony_function_sent_; 1472 bool allow_harmony_function_sent_;
1469 bool allow_harmony_restrictive_generators_; 1473 bool allow_harmony_restrictive_generators_;
1470 bool allow_harmony_trailing_commas_; 1474 bool allow_harmony_trailing_commas_;
1471 bool allow_harmony_class_fields_; 1475 bool allow_harmony_class_fields_;
1472 bool allow_harmony_object_rest_spread_; 1476 bool allow_harmony_object_rest_spread_;
1477 bool allow_harmony_async_iteration_;
1473 1478
1474 friend class DiscardableZoneScope; 1479 friend class DiscardableZoneScope;
1475 }; 1480 };
1476 1481
1477 template <typename Impl> 1482 template <typename Impl>
1478 ParserBase<Impl>::FunctionState::FunctionState( 1483 ParserBase<Impl>::FunctionState::FunctionState(
1479 FunctionState** function_state_stack, ScopeState** scope_stack, 1484 FunctionState** function_state_stack, ScopeState** scope_stack,
1480 DeclarationScope* scope) 1485 DeclarationScope* scope)
1481 : ScopeState(scope_stack, scope), 1486 : ScopeState(scope_stack, scope),
1482 next_materialized_literal_index_(0), 1487 next_materialized_literal_index_(0),
(...skipping 3265 matching lines...) Expand 10 before | Expand all | Expand 10 after
4748 case Token::SEMICOLON: 4753 case Token::SEMICOLON:
4749 Next(); 4754 Next();
4750 return factory()->NewEmptyStatement(kNoSourcePosition); 4755 return factory()->NewEmptyStatement(kNoSourcePosition);
4751 case Token::IF: 4756 case Token::IF:
4752 return ParseIfStatement(labels, ok); 4757 return ParseIfStatement(labels, ok);
4753 case Token::DO: 4758 case Token::DO:
4754 return ParseDoWhileStatement(labels, ok); 4759 return ParseDoWhileStatement(labels, ok);
4755 case Token::WHILE: 4760 case Token::WHILE:
4756 return ParseWhileStatement(labels, ok); 4761 return ParseWhileStatement(labels, ok);
4757 case Token::FOR: 4762 case Token::FOR:
4763 if (V8_UNLIKELY(allow_harmony_async_iteration() && is_async_function() &&
4764 PeekAhead() == Token::AWAIT)) {
4765 return ParseForAwaitStatement(labels, ok);
4766 }
4758 return ParseForStatement(labels, ok); 4767 return ParseForStatement(labels, ok);
4759 case Token::CONTINUE: 4768 case Token::CONTINUE:
4760 case Token::BREAK: 4769 case Token::BREAK:
4761 case Token::RETURN: 4770 case Token::RETURN:
4762 case Token::THROW: 4771 case Token::THROW:
4763 case Token::TRY: { 4772 case Token::TRY: {
4764 // These statements must have their labels preserved in an enclosing 4773 // These statements must have their labels preserved in an enclosing
4765 // block, as the corresponding AST nodes do not currently store their 4774 // block, as the corresponding AST nodes do not currently store their
4766 // labels. 4775 // labels.
4767 // TODO(nikolaos, marja): Consider adding the labels to the AST nodes. 4776 // TODO(nikolaos, marja): Consider adding the labels to the AST nodes.
(...skipping 857 matching lines...) Expand 10 before | Expand all | Expand 10 after
5625 block->set_scope(for_scope); 5634 block->set_scope(for_scope);
5626 loop->Initialize(init, cond, next, body); 5635 loop->Initialize(init, cond, next, body);
5627 return block; 5636 return block;
5628 } else { 5637 } else {
5629 loop->Initialize(init, cond, next, body); 5638 loop->Initialize(init, cond, next, body);
5630 return loop; 5639 return loop;
5631 } 5640 }
5632 } 5641 }
5633 } 5642 }
5634 5643
5644 template <typename Impl>
5645 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseForAwaitStatement(
5646 ZoneList<const AstRawString*>* labels, bool* ok) {
5647 // for await '(' ForDeclaration of AssignmentExpression ')'
5648 DCHECK(is_async_function());
5649 DCHECK(allow_harmony_async_iteration());
5650
5651 int stmt_pos = peek_position();
5652
5653 ForInfo for_info(this);
5654 for_info.mode = ForEachStatement::ITERATE;
5655
5656 // Create an in-between scope for let-bound iteration variables.
5657 BlockState for_state(zone(), &scope_state_);
5658 Expect(Token::FOR, CHECK_OK);
5659 Expect(Token::AWAIT, CHECK_OK);
5660 Expect(Token::LPAREN, CHECK_OK);
5661 for_state.set_start_position(scanner()->location().beg_pos);
5662 for_state.set_is_hidden();
5663
5664 auto loop = factory()->NewForEachStatement(for_info.mode, labels, stmt_pos);
5665 typename Types::Target target(this, loop);
5666
5667 ExpressionT each_variable = impl()->EmptyExpression();
5668
5669 bool has_declarations = false;
5670
5671 switch (peek()) {
5672 case Token::LET:
5673 if (!IsNextLetKeyword()) goto parse_lhs;
5674 /* falls through */
5675 case Token::VAR:
5676 case Token::CONST: {
5677 // The initializer contains declarations
5678 // 'for' 'await' '(' ForDeclaration 'of' AssignmentExpression ')'
5679 // Statement
5680 // 'for' 'await' '(' 'var' ForBinding 'of' AssignmentExpression ')'
5681 // Statement
5682 has_declarations = true;
5683 ParseVariableDeclarations(kForStatement, &for_info.parsing_result,
5684 nullptr, CHECK_OK);
5685 for_info.position = scanner()->location().beg_pos;
5686
5687 // Only a single declaration is allowed in for-await-of loops
5688 if (for_info.parsing_result.declarations.length() != 1) {
5689 impl()->ReportMessageAt(for_info.parsing_result.bindings_loc,
5690 MessageTemplate::kForInOfLoopMultiBindings,
5691 "for-await-of");
5692 *ok = false;
5693 return impl()->NullStatement();
5694 }
5695
5696 // for-await-of's declarations do not permit initializers.
5697 if (for_info.parsing_result.first_initializer_loc.IsValid()) {
5698 impl()->ReportMessageAt(for_info.parsing_result.first_initializer_loc,
5699 MessageTemplate::kForInOfLoopInitializer,
5700 "for-await-of");
5701 *ok = false;
5702 return impl()->NullStatement();
5703 }
5704 break;
5705 }
5706
5707 default:
5708 parse_lhs : {
5709 // The initializer does not contain declarations.
5710 // 'for' 'await' '(' LeftHandSideExpression 'of' AssignmentExpression ')'
5711 // Statement
5712 int lhs_beg_pos = peek_position();
5713 ExpressionClassifier classifier(this);
5714 ExpressionT lhs = each_variable = ParseLeftHandSideExpression(CHECK_OK);
5715 int lhs_end_pos = scanner()->location().end_pos;
5716
5717 if (lhs->IsArrayLiteral() || lhs->IsObjectLiteral()) {
5718 ValidateAssignmentPattern(CHECK_OK);
5719 } else {
5720 impl()->RewriteNonPattern(CHECK_OK);
5721 each_variable = impl()->CheckAndRewriteReferenceExpression(
5722 lhs, lhs_beg_pos, lhs_end_pos, MessageTemplate::kInvalidLhsInFor,
5723 kSyntaxError, CHECK_OK);
5724 }
5725 } break;
5726 }
5727
5728 ExpectContextualKeyword(CStrVector("of"), CHECK_OK);
5729 int each_keyword_pos = scanner()->location().beg_pos;
5730
5731 const bool kAllowIn = true;
5732 ExpressionT iterable = impl()->EmptyExpression();
5733
5734 {
5735 ExpressionClassifier classifier(this);
5736 iterable = ParseAssignmentExpression(kAllowIn, CHECK_OK);
5737 impl()->RewriteNonPattern(CHECK_OK);
5738 }
5739
5740 Expect(Token::RPAREN, CHECK_OK);
5741
5742 StatementT final_loop = impl()->NullStatement();
5743 {
5744 ReturnExprScope no_tail_calls(function_state_,
5745 ReturnExprContext::kInsideForInOfBody);
5746 BlockState block_state(zone(), &scope_state_);
5747 block_state.set_start_position(scanner()->location().beg_pos);
5748
5749 // For legacy compat reasons, give for loops similar treatment to
5750 // if statements in allowing a function declaration for a body
5751 StatementT body = ParseScopedStatement(nullptr, true, CHECK_OK);
5752 block_state.set_end_position(scanner()->location().end_pos);
5753
5754 if (has_declarations) {
5755 BlockT body_block = impl()->NullBlock();
5756 impl()->DesugarBindingInForEachStatement(&for_info, &body_block,
5757 &each_variable, CHECK_OK);
5758 body_block->statements()->Add(body, zone());
5759 body_block->set_scope(block_state.FinalizedBlockScope());
5760 for_state.set_end_position(scanner()->location().end_pos);
5761
5762 const bool finalize = true;
5763 final_loop = impl()->InitializeForOfStatement(
5764 loop, each_variable, iterable, body_block, finalize,
5765 IteratorType::kAsync, each_keyword_pos);
5766 } else {
5767 const bool finalize = true;
5768 final_loop = impl()->InitializeForOfStatement(
5769 loop, each_variable, iterable, body, finalize, IteratorType::kAsync,
5770 each_keyword_pos);
5771
5772 Scope* for_scope = for_state.FinalizedBlockScope();
5773 DCHECK_NULL(for_scope);
5774 USE(for_scope);
5775 Scope* block_scope = block_state.FinalizedBlockScope();
5776 DCHECK_NULL(block_scope);
5777 USE(block_scope);
5778 return final_loop;
5779 }
5780 }
5781
5782 DCHECK(has_declarations);
5783 BlockT init_block =
5784 impl()->CreateForEachStatementTDZ(impl()->NullBlock(), for_info, ok);
5785
5786 for_state.set_end_position(scanner()->location().end_pos);
5787 Scope* for_scope = for_state.FinalizedBlockScope();
5788 // Parsed for-in loop w/ variable declarations.
5789 if (!impl()->IsNullStatement(init_block)) {
5790 init_block->statements()->Add(final_loop, zone());
5791 init_block->set_scope(for_scope);
5792 return init_block;
5793 }
5794 DCHECK_NULL(for_scope);
5795 return final_loop;
5796 }
5797
5635 #undef CHECK_OK 5798 #undef CHECK_OK
5636 #undef CHECK_OK_CUSTOM 5799 #undef CHECK_OK_CUSTOM
5637 5800
5638 template <typename Impl> 5801 template <typename Impl>
5639 void ParserBase<Impl>::ObjectLiteralChecker::CheckDuplicateProto( 5802 void ParserBase<Impl>::ObjectLiteralChecker::CheckDuplicateProto(
5640 Token::Value property) { 5803 Token::Value property) {
5641 if (property == Token::SMI || property == Token::NUMBER) return; 5804 if (property == Token::SMI || property == Token::NUMBER) return;
5642 5805
5643 if (IsProto()) { 5806 if (IsProto()) {
5644 if (has_seen_proto_) { 5807 if (has_seen_proto_) {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
5684 return; 5847 return;
5685 } 5848 }
5686 } 5849 }
5687 5850
5688 #undef CHECK_OK_VOID 5851 #undef CHECK_OK_VOID
5689 5852
5690 } // namespace internal 5853 } // namespace internal
5691 } // namespace v8 5854 } // namespace v8
5692 5855
5693 #endif // V8_PARSING_PARSER_BASE_H 5856 #endif // V8_PARSING_PARSER_BASE_H
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698