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

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: remove that comment Created 3 years, 10 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 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
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_dynamic_import_(false) {} 228 allow_harmony_dynamic_import_(false),
229 allow_harmony_async_iteration_(false) {}
229 230
230 #define ALLOW_ACCESSORS(name) \ 231 #define ALLOW_ACCESSORS(name) \
231 bool allow_##name() const { return allow_##name##_; } \ 232 bool allow_##name() const { return allow_##name##_; } \
232 void set_allow_##name(bool allow) { allow_##name##_ = allow; } 233 void set_allow_##name(bool allow) { allow_##name##_ = allow; }
233 234
234 ALLOW_ACCESSORS(natives); 235 ALLOW_ACCESSORS(natives);
235 ALLOW_ACCESSORS(tailcalls); 236 ALLOW_ACCESSORS(tailcalls);
236 ALLOW_ACCESSORS(harmony_do_expressions); 237 ALLOW_ACCESSORS(harmony_do_expressions);
237 ALLOW_ACCESSORS(harmony_function_sent); 238 ALLOW_ACCESSORS(harmony_function_sent);
238 ALLOW_ACCESSORS(harmony_restrictive_generators); 239 ALLOW_ACCESSORS(harmony_restrictive_generators);
239 ALLOW_ACCESSORS(harmony_trailing_commas); 240 ALLOW_ACCESSORS(harmony_trailing_commas);
240 ALLOW_ACCESSORS(harmony_class_fields); 241 ALLOW_ACCESSORS(harmony_class_fields);
241 ALLOW_ACCESSORS(harmony_object_rest_spread); 242 ALLOW_ACCESSORS(harmony_object_rest_spread);
242 ALLOW_ACCESSORS(harmony_dynamic_import); 243 ALLOW_ACCESSORS(harmony_dynamic_import);
244 ALLOW_ACCESSORS(harmony_async_iteration);
243 245
244 #undef ALLOW_ACCESSORS 246 #undef ALLOW_ACCESSORS
245 247
246 uintptr_t stack_limit() const { return stack_limit_; } 248 uintptr_t stack_limit() const { return stack_limit_; }
247 249
248 void set_stack_limit(uintptr_t stack_limit) { stack_limit_ = stack_limit; } 250 void set_stack_limit(uintptr_t stack_limit) { stack_limit_ = stack_limit; }
249 251
250 void set_default_eager_compile_hint( 252 void set_default_eager_compile_hint(
251 FunctionLiteral::EagerCompileHint eager_compile_hint) { 253 FunctionLiteral::EagerCompileHint eager_compile_hint) {
252 default_eager_compile_hint_ = eager_compile_hint; 254 default_eager_compile_hint_ = eager_compile_hint;
(...skipping 1032 matching lines...) Expand 10 before | Expand all | Expand 10 after
1285 int stmt_pos, ExpressionT expression, int lhs_beg_pos, int lhs_end_pos, 1287 int stmt_pos, ExpressionT expression, int lhs_beg_pos, int lhs_end_pos,
1286 ForInfo* for_info, BlockState* for_state, 1288 ForInfo* for_info, BlockState* for_state,
1287 ZoneList<const AstRawString*>* labels, bool* ok); 1289 ZoneList<const AstRawString*>* labels, bool* ok);
1288 1290
1289 // Parse a C-style for loop: 'for (<init>; <cond>; <step>) { ... }' 1291 // Parse a C-style for loop: 'for (<init>; <cond>; <step>) { ... }'
1290 StatementT ParseStandardForLoop(int stmt_pos, StatementT init, 1292 StatementT ParseStandardForLoop(int stmt_pos, StatementT init,
1291 bool bound_names_are_lexical, 1293 bool bound_names_are_lexical,
1292 ForInfo* for_info, BlockState* for_state, 1294 ForInfo* for_info, BlockState* for_state,
1293 ZoneList<const AstRawString*>* labels, 1295 ZoneList<const AstRawString*>* labels,
1294 bool* ok); 1296 bool* ok);
1297 StatementT ParseForAwaitStatement(ZoneList<const AstRawString*>* labels,
1298 bool* ok);
1295 1299
1296 bool IsNextLetKeyword(); 1300 bool IsNextLetKeyword();
1297 bool IsTrivialExpression(); 1301 bool IsTrivialExpression();
1298 1302
1299 // Checks if the expression is a valid reference expression (e.g., on the 1303 // Checks if the expression is a valid reference expression (e.g., on the
1300 // left-hand side of assignments). Although ruled out by ECMA as early errors, 1304 // left-hand side of assignments). Although ruled out by ECMA as early errors,
1301 // we allow calls for web compatibility and rewrite them to a runtime throw. 1305 // we allow calls for web compatibility and rewrite them to a runtime throw.
1302 ExpressionT CheckAndRewriteReferenceExpression( 1306 ExpressionT CheckAndRewriteReferenceExpression(
1303 ExpressionT expression, int beg_pos, int end_pos, 1307 ExpressionT expression, int beg_pos, int end_pos,
1304 MessageTemplate::Template message, bool* ok); 1308 MessageTemplate::Template message, bool* ok);
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
1481 1485
1482 bool allow_natives_; 1486 bool allow_natives_;
1483 bool allow_tailcalls_; 1487 bool allow_tailcalls_;
1484 bool allow_harmony_do_expressions_; 1488 bool allow_harmony_do_expressions_;
1485 bool allow_harmony_function_sent_; 1489 bool allow_harmony_function_sent_;
1486 bool allow_harmony_restrictive_generators_; 1490 bool allow_harmony_restrictive_generators_;
1487 bool allow_harmony_trailing_commas_; 1491 bool allow_harmony_trailing_commas_;
1488 bool allow_harmony_class_fields_; 1492 bool allow_harmony_class_fields_;
1489 bool allow_harmony_object_rest_spread_; 1493 bool allow_harmony_object_rest_spread_;
1490 bool allow_harmony_dynamic_import_; 1494 bool allow_harmony_dynamic_import_;
1495 bool allow_harmony_async_iteration_;
1491 1496
1492 friend class DiscardableZoneScope; 1497 friend class DiscardableZoneScope;
1493 }; 1498 };
1494 1499
1495 template <typename Impl> 1500 template <typename Impl>
1496 ParserBase<Impl>::FunctionState::FunctionState( 1501 ParserBase<Impl>::FunctionState::FunctionState(
1497 FunctionState** function_state_stack, ScopeState** scope_stack, 1502 FunctionState** function_state_stack, ScopeState** scope_stack,
1498 DeclarationScope* scope) 1503 DeclarationScope* scope)
1499 : ScopeState(scope_stack, scope), 1504 : ScopeState(scope_stack, scope),
1500 next_materialized_literal_index_(0), 1505 next_materialized_literal_index_(0),
(...skipping 3287 matching lines...) Expand 10 before | Expand all | Expand 10 after
4788 case Token::SEMICOLON: 4793 case Token::SEMICOLON:
4789 Next(); 4794 Next();
4790 return factory()->NewEmptyStatement(kNoSourcePosition); 4795 return factory()->NewEmptyStatement(kNoSourcePosition);
4791 case Token::IF: 4796 case Token::IF:
4792 return ParseIfStatement(labels, ok); 4797 return ParseIfStatement(labels, ok);
4793 case Token::DO: 4798 case Token::DO:
4794 return ParseDoWhileStatement(labels, ok); 4799 return ParseDoWhileStatement(labels, ok);
4795 case Token::WHILE: 4800 case Token::WHILE:
4796 return ParseWhileStatement(labels, ok); 4801 return ParseWhileStatement(labels, ok);
4797 case Token::FOR: 4802 case Token::FOR:
4803 if (V8_UNLIKELY(allow_harmony_async_iteration() && is_async_function() &&
4804 PeekAhead() == Token::AWAIT)) {
4805 return ParseForAwaitStatement(labels, ok);
4806 }
4798 return ParseForStatement(labels, ok); 4807 return ParseForStatement(labels, ok);
4799 case Token::CONTINUE: 4808 case Token::CONTINUE:
4800 case Token::BREAK: 4809 case Token::BREAK:
4801 case Token::RETURN: 4810 case Token::RETURN:
4802 case Token::THROW: 4811 case Token::THROW:
4803 case Token::TRY: { 4812 case Token::TRY: {
4804 // These statements must have their labels preserved in an enclosing 4813 // These statements must have their labels preserved in an enclosing
4805 // block, as the corresponding AST nodes do not currently store their 4814 // block, as the corresponding AST nodes do not currently store their
4806 // labels. 4815 // labels.
4807 // TODO(nikolaos, marja): Consider adding the labels to the AST nodes. 4816 // TODO(nikolaos, marja): Consider adding the labels to the AST nodes.
(...skipping 886 matching lines...) Expand 10 before | Expand all | Expand 10 after
5694 } 5703 }
5695 5704
5696 template <typename Impl> 5705 template <typename Impl>
5697 void ParserBase<Impl>::MarkLoopVariableAsAssigned(Scope* scope, Variable* var) { 5706 void ParserBase<Impl>::MarkLoopVariableAsAssigned(Scope* scope, Variable* var) {
5698 if (!IsLexicalVariableMode(var->mode()) && !scope->is_function_scope()) { 5707 if (!IsLexicalVariableMode(var->mode()) && !scope->is_function_scope()) {
5699 var->set_maybe_assigned(); 5708 var->set_maybe_assigned();
5700 } 5709 }
5701 } 5710 }
5702 5711
5703 template <typename Impl> 5712 template <typename Impl>
5713 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseForAwaitStatement(
5714 ZoneList<const AstRawString*>* labels, bool* ok) {
5715 // for await '(' ForDeclaration of AssignmentExpression ')'
5716 DCHECK(is_async_function());
5717 DCHECK(allow_harmony_async_iteration());
5718
5719 int stmt_pos = peek_position();
5720
5721 ForInfo for_info(this);
5722 for_info.mode = ForEachStatement::ITERATE;
5723
5724 // Create an in-between scope for let-bound iteration variables.
5725 BlockState for_state(zone(), &scope_state_);
5726 Expect(Token::FOR, CHECK_OK);
5727 Expect(Token::AWAIT, CHECK_OK);
5728 Expect(Token::LPAREN, CHECK_OK);
5729 for_state.set_start_position(scanner()->location().beg_pos);
5730 for_state.set_is_hidden();
5731
5732 auto loop = factory()->NewForOfStatement(labels, stmt_pos);
5733 typename Types::Target target(this, loop);
5734
5735 ExpressionT each_variable = impl()->EmptyExpression();
5736
5737 bool has_declarations = false;
5738
5739 if (peek() == Token::VAR || peek() == Token::CONST ||
5740 (peek() == Token::LET && IsNextLetKeyword())) {
5741 // The initializer contains declarations
5742 // 'for' 'await' '(' ForDeclaration 'of' AssignmentExpression ')'
5743 // Statement
5744 // 'for' 'await' '(' 'var' ForBinding 'of' AssignmentExpression ')'
5745 // Statement
5746 has_declarations = true;
5747 ParseVariableDeclarations(kForStatement, &for_info.parsing_result, nullptr,
5748 CHECK_OK);
5749 for_info.position = scanner()->location().beg_pos;
5750
5751 // Only a single declaration is allowed in for-await-of loops
5752 if (for_info.parsing_result.declarations.length() != 1) {
5753 impl()->ReportMessageAt(for_info.parsing_result.bindings_loc,
5754 MessageTemplate::kForInOfLoopMultiBindings,
5755 "for-await-of");
5756 *ok = false;
5757 return impl()->NullStatement();
5758 }
5759
5760 // for-await-of's declarations do not permit initializers.
5761 if (for_info.parsing_result.first_initializer_loc.IsValid()) {
5762 impl()->ReportMessageAt(for_info.parsing_result.first_initializer_loc,
5763 MessageTemplate::kForInOfLoopInitializer,
5764 "for-await-of");
5765 *ok = false;
5766 return impl()->NullStatement();
5767 }
5768 } else {
5769 // The initializer does not contain declarations.
5770 // 'for' 'await' '(' LeftHandSideExpression 'of' AssignmentExpression ')'
5771 // Statement
5772 int lhs_beg_pos = peek_position();
5773 ExpressionClassifier classifier(this);
5774 ExpressionT lhs = each_variable = ParseLeftHandSideExpression(CHECK_OK);
5775 int lhs_end_pos = scanner()->location().end_pos;
5776
5777 if (lhs->IsArrayLiteral() || lhs->IsObjectLiteral()) {
5778 ValidateAssignmentPattern(CHECK_OK);
5779 } else {
5780 impl()->RewriteNonPattern(CHECK_OK);
5781 each_variable = impl()->CheckAndRewriteReferenceExpression(
5782 lhs, lhs_beg_pos, lhs_end_pos, MessageTemplate::kInvalidLhsInFor,
5783 kSyntaxError, CHECK_OK);
5784 }
5785 }
5786
5787 ExpectContextualKeyword(CStrVector("of"), CHECK_OK);
5788 int each_keyword_pos = scanner()->location().beg_pos;
5789
5790 const bool kAllowIn = true;
5791 ExpressionT iterable = impl()->EmptyExpression();
5792
5793 {
5794 ExpressionClassifier classifier(this);
5795 iterable = ParseAssignmentExpression(kAllowIn, CHECK_OK);
5796 impl()->RewriteNonPattern(CHECK_OK);
5797 }
5798
5799 Expect(Token::RPAREN, CHECK_OK);
5800
5801 StatementT final_loop = impl()->NullStatement();
5802 {
5803 ReturnExprScope no_tail_calls(function_state_,
5804 ReturnExprContext::kInsideForInOfBody);
5805 BlockState block_state(zone(), &scope_state_);
5806 block_state.set_start_position(scanner()->location().beg_pos);
5807
5808 const bool kDisallowLabelledFunctionStatement = true;
5809 StatementT body = ParseScopedStatement(
5810 nullptr, kDisallowLabelledFunctionStatement, CHECK_OK);
5811 block_state.set_end_position(scanner()->location().end_pos);
5812
5813 if (has_declarations) {
5814 BlockT body_block = impl()->NullBlock();
5815 impl()->DesugarBindingInForEachStatement(&for_info, &body_block,
5816 &each_variable, CHECK_OK);
5817 body_block->statements()->Add(body, zone());
5818 body_block->set_scope(block_state.FinalizedBlockScope());
5819 for_state.set_end_position(scanner()->location().end_pos);
5820
5821 const bool finalize = true;
5822 final_loop = impl()->InitializeForOfStatement(
5823 loop, each_variable, iterable, body_block, finalize,
5824 IteratorType::kAsync, each_keyword_pos);
5825 } else {
5826 const bool finalize = true;
5827 final_loop = impl()->InitializeForOfStatement(
5828 loop, each_variable, iterable, body, finalize, IteratorType::kAsync,
5829 each_keyword_pos);
5830
5831 Scope* for_scope = for_state.FinalizedBlockScope();
5832 DCHECK_NULL(for_scope);
5833 USE(for_scope);
5834 Scope* block_scope = block_state.FinalizedBlockScope();
5835 DCHECK_NULL(block_scope);
5836 USE(block_scope);
5837 return final_loop;
5838 }
5839 }
5840
5841 DCHECK(has_declarations);
5842 BlockT init_block =
5843 impl()->CreateForEachStatementTDZ(impl()->NullBlock(), for_info, ok);
5844
5845 for_state.set_end_position(scanner()->location().end_pos);
5846 Scope* for_scope = for_state.FinalizedBlockScope();
5847 // Parsed for-in loop w/ variable declarations.
5848 if (!impl()->IsNullStatement(init_block)) {
5849 init_block->statements()->Add(final_loop, zone());
5850 init_block->set_scope(for_scope);
5851 return init_block;
5852 }
5853 DCHECK_NULL(for_scope);
5854 return final_loop;
5855 }
5856
5857 template <typename Impl>
5704 void ParserBase<Impl>::ObjectLiteralChecker::CheckDuplicateProto( 5858 void ParserBase<Impl>::ObjectLiteralChecker::CheckDuplicateProto(
5705 Token::Value property) { 5859 Token::Value property) {
5706 if (property == Token::SMI || property == Token::NUMBER) return; 5860 if (property == Token::SMI || property == Token::NUMBER) return;
5707 5861
5708 if (IsProto()) { 5862 if (IsProto()) {
5709 if (has_seen_proto_) { 5863 if (has_seen_proto_) {
5710 this->parser()->classifier()->RecordExpressionError( 5864 this->parser()->classifier()->RecordExpressionError(
5711 this->scanner()->location(), MessageTemplate::kDuplicateProto); 5865 this->scanner()->location(), MessageTemplate::kDuplicateProto);
5712 return; 5866 return;
5713 } 5867 }
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
5751 } 5905 }
5752 5906
5753 #undef CHECK_OK 5907 #undef CHECK_OK
5754 #undef CHECK_OK_CUSTOM 5908 #undef CHECK_OK_CUSTOM
5755 #undef CHECK_OK_VOID 5909 #undef CHECK_OK_VOID
5756 5910
5757 } // namespace internal 5911 } // namespace internal
5758 } // namespace v8 5912 } // namespace v8
5759 5913
5760 #endif // V8_PARSING_PARSER_BASE_H 5914 #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