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

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

Issue 2351233002: [parser] Refactor of Parse*Statement*, part 8 (Closed)
Patch Set: The real patch Created 4 years, 3 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 638 matching lines...) Expand 10 before | Expand all | Expand 10 after
649 Variable* variable; 649 Variable* variable;
650 ExpressionT pattern; 650 ExpressionT pattern;
651 Scope* scope; 651 Scope* scope;
652 BlockT init_block; 652 BlockT init_block;
653 BlockT inner_block; 653 BlockT inner_block;
654 bool for_promise_reject; 654 bool for_promise_reject;
655 ZoneList<const AstRawString*> bound_names; 655 ZoneList<const AstRawString*> bound_names;
656 TailCallExpressionList tail_call_expressions; 656 TailCallExpressionList tail_call_expressions;
657 }; 657 };
658 658
659 struct ForInfo {
660 public:
661 explicit ForInfo(ParserBase* parser)
662 : bound_names(1, parser->zone()),
663 bound_names_are_lexical(false),
664 mode(ForEachStatement::ENUMERATE),
665 each_loc(),
666 parsing_result() {}
667 ZoneList<const AstRawString*> bound_names;
668 bool bound_names_are_lexical;
669 ForEachStatement::VisitMode mode;
670 Scanner::Location each_loc;
671 DeclarationParsingResult parsing_result;
672 };
673
659 DeclarationScope* NewScriptScope() const { 674 DeclarationScope* NewScriptScope() const {
660 return new (zone()) DeclarationScope(zone(), ast_value_factory()); 675 return new (zone()) DeclarationScope(zone(), ast_value_factory());
661 } 676 }
662 677
663 DeclarationScope* NewVarblockScope() const { 678 DeclarationScope* NewVarblockScope() const {
664 return new (zone()) DeclarationScope(zone(), scope(), BLOCK_SCOPE); 679 return new (zone()) DeclarationScope(zone(), scope(), BLOCK_SCOPE);
665 } 680 }
666 681
667 ModuleScope* NewModuleScope(DeclarationScope* parent) const { 682 ModuleScope* NewModuleScope(DeclarationScope* parent) const {
668 return new (zone()) ModuleScope(parent, ast_value_factory()); 683 return new (zone()) ModuleScope(parent, ast_value_factory());
(...skipping 574 matching lines...) Expand 10 before | Expand all | Expand 10 after
1243 StatementT ParseWithStatement(ZoneList<const AstRawString*>* labels, 1258 StatementT ParseWithStatement(ZoneList<const AstRawString*>* labels,
1244 bool* ok); 1259 bool* ok);
1245 StatementT ParseDoWhileStatement(ZoneList<const AstRawString*>* labels, 1260 StatementT ParseDoWhileStatement(ZoneList<const AstRawString*>* labels,
1246 bool* ok); 1261 bool* ok);
1247 StatementT ParseWhileStatement(ZoneList<const AstRawString*>* labels, 1262 StatementT ParseWhileStatement(ZoneList<const AstRawString*>* labels,
1248 bool* ok); 1263 bool* ok);
1249 StatementT ParseThrowStatement(bool* ok); 1264 StatementT ParseThrowStatement(bool* ok);
1250 StatementT ParseSwitchStatement(ZoneList<const AstRawString*>* labels, 1265 StatementT ParseSwitchStatement(ZoneList<const AstRawString*>* labels,
1251 bool* ok); 1266 bool* ok);
1252 StatementT ParseTryStatement(bool* ok); 1267 StatementT ParseTryStatement(bool* ok);
1253 Statement* ParseForStatement(ZoneList<const AstRawString*>* labels, bool* ok); 1268 StatementT ParseForStatement(ZoneList<const AstRawString*>* labels, bool* ok);
1254 1269
1255 bool IsNextLetKeyword(); 1270 bool IsNextLetKeyword();
1256 bool IsTrivialExpression(); 1271 bool IsTrivialExpression();
1257 1272
1258 // Checks if the expression is a valid reference expression (e.g., on the 1273 // Checks if the expression is a valid reference expression (e.g., on the
1259 // left-hand side of assignments). Although ruled out by ECMA as early errors, 1274 // left-hand side of assignments). Although ruled out by ECMA as early errors,
1260 // we allow calls for web compatibility and rewrite them to a runtime throw. 1275 // we allow calls for web compatibility and rewrite them to a runtime throw.
1261 ExpressionT CheckAndRewriteReferenceExpression( 1276 ExpressionT CheckAndRewriteReferenceExpression(
1262 ExpressionT expression, int beg_pos, int end_pos, 1277 ExpressionT expression, int beg_pos, int end_pos,
1263 MessageTemplate::Template message, bool* ok); 1278 MessageTemplate::Template message, bool* ok);
(...skipping 3079 matching lines...) Expand 10 before | Expand all | Expand 10 after
4343 case Token::SEMICOLON: 4358 case Token::SEMICOLON:
4344 Next(); 4359 Next();
4345 return factory()->NewEmptyStatement(kNoSourcePosition); 4360 return factory()->NewEmptyStatement(kNoSourcePosition);
4346 case Token::IF: 4361 case Token::IF:
4347 return ParseIfStatement(labels, ok); 4362 return ParseIfStatement(labels, ok);
4348 case Token::DO: 4363 case Token::DO:
4349 return ParseDoWhileStatement(labels, ok); 4364 return ParseDoWhileStatement(labels, ok);
4350 case Token::WHILE: 4365 case Token::WHILE:
4351 return ParseWhileStatement(labels, ok); 4366 return ParseWhileStatement(labels, ok);
4352 case Token::FOR: 4367 case Token::FOR:
4353 return impl()->ParseForStatement(labels, ok); 4368 return ParseForStatement(labels, ok);
4354 case Token::CONTINUE: 4369 case Token::CONTINUE:
4355 case Token::BREAK: 4370 case Token::BREAK:
4356 case Token::RETURN: 4371 case Token::RETURN:
4357 case Token::THROW: 4372 case Token::THROW:
4358 case Token::TRY: { 4373 case Token::TRY: {
4359 // These statements must have their labels preserved in an enclosing 4374 // These statements must have their labels preserved in an enclosing
4360 // block, as the corresponding AST nodes do not currently store their 4375 // block, as the corresponding AST nodes do not currently store their
4361 // labels. 4376 // labels.
4362 // TODO(nikolaos, marja): Consider adding the labels to the AST nodes. 4377 // TODO(nikolaos, marja): Consider adding the labels to the AST nodes.
4363 if (labels == nullptr) { 4378 if (labels == nullptr) {
(...skipping 606 matching lines...) Expand 10 before | Expand all | Expand 10 after
4970 MessageTemplate::kUnexpectedTailCallInCatchBlock); 4985 MessageTemplate::kUnexpectedTailCallInCatchBlock);
4971 *ok = false; 4986 *ok = false;
4972 return impl()->NullStatement(); 4987 return impl()->NullStatement();
4973 } 4988 }
4974 } 4989 }
4975 4990
4976 return impl()->RewriteTryStatement(try_block, catch_block, finally_block, 4991 return impl()->RewriteTryStatement(try_block, catch_block, finally_block,
4977 catch_info, pos); 4992 catch_info, pos);
4978 } 4993 }
4979 4994
4980 Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels, 4995 template <typename Impl>
4981 bool* ok) { 4996 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseForStatement(
4997 ZoneList<const AstRawString*>* labels, bool* ok) {
4982 int stmt_pos = peek_position(); 4998 int stmt_pos = peek_position();
4983 Statement* init = NULL; 4999 ForInfo for_info(this);
4984 ZoneList<const AstRawString*> bound_names(1, zone());
4985 bool bound_names_are_lexical = false;
4986 5000
4987 // Create an in-between scope for let-bound iteration variables. 5001 // Create an in-between scope for let-bound iteration variables.
4988 BlockState for_state(&scope_state_); 5002 BlockState for_state(&scope_state_);
4989 Expect(Token::FOR, CHECK_OK); 5003 Expect(Token::FOR, CHECK_OK);
4990 Expect(Token::LPAREN, CHECK_OK); 5004 Expect(Token::LPAREN, CHECK_OK);
4991 for_state.set_start_position(scanner()->location().beg_pos); 5005 for_state.set_start_position(scanner()->location().beg_pos);
4992 for_state.set_is_hidden(); 5006 for_state.set_is_hidden();
4993 DeclarationParsingResult parsing_result; 5007
5008 StatementT init = impl()->NullStatement();
4994 if (peek() != Token::SEMICOLON) { 5009 if (peek() != Token::SEMICOLON) {
5010 // An initializer is present.
4995 if (peek() == Token::VAR || peek() == Token::CONST || 5011 if (peek() == Token::VAR || peek() == Token::CONST ||
4996 (peek() == Token::LET && IsNextLetKeyword())) { 5012 (peek() == Token::LET && IsNextLetKeyword())) {
4997 ParseVariableDeclarations(kForStatement, &parsing_result, nullptr, 5013 // The initializer contains declarations.
4998 CHECK_OK); 5014 ParseVariableDeclarations(kForStatement, &for_info.parsing_result,
5015 nullptr, CHECK_OK);
5016 for_info.bound_names_are_lexical =
marja 2016/09/20 19:36:30 bound_names_are_lexical is now redundant, right? M
nickie 2016/09/21 09:20:02 Yes. I'm removing it from ForInfo but I'm keeping
5017 IsLexicalVariableMode(for_info.parsing_result.descriptor.mode);
5018 for_info.each_loc = scanner()->location();
4999 5019
5000 ForEachStatement::VisitMode mode = ForEachStatement::ENUMERATE; 5020 if (CheckInOrOf(&for_info.mode)) {
5001 int each_beg_pos = scanner()->location().beg_pos; 5021 // Just one declaration followed by in/of.
5002 int each_end_pos = scanner()->location().end_pos; 5022 if (for_info.parsing_result.declarations.length() != 1) {
5003 5023 impl()->ReportMessageAt(
5004 if (CheckInOrOf(&mode)) { 5024 for_info.parsing_result.bindings_loc,
5005 if (parsing_result.declarations.length() != 1) { 5025 MessageTemplate::kForInOfLoopMultiBindings,
5006 ReportMessageAt(parsing_result.bindings_loc, 5026 ForEachStatement::VisitModeString(for_info.mode));
5007 MessageTemplate::kForInOfLoopMultiBindings,
5008 ForEachStatement::VisitModeString(mode));
5009 *ok = false; 5027 *ok = false;
5010 return nullptr; 5028 return impl()->NullStatement();
5011 } 5029 }
5012 DeclarationParsingResult::Declaration& decl = 5030 if (for_info.parsing_result.first_initializer_loc.IsValid() &&
5013 parsing_result.declarations[0]; 5031 (is_strict(language_mode()) ||
5014 if (parsing_result.first_initializer_loc.IsValid() && 5032 for_info.mode == ForEachStatement::ITERATE ||
marja 2016/09/21 08:23:21 Random whining unrelated to this CL: Why do we nee
nickie 2016/09/21 09:20:02 I agree. Also, it seems that this is used only lo
5015 (is_strict(language_mode()) || mode == ForEachStatement::ITERATE || 5033 IsLexicalVariableMode(for_info.parsing_result.descriptor.mode) ||
5016 IsLexicalVariableMode(parsing_result.descriptor.mode) || 5034 !impl()->IsIdentifier(
5017 !decl.pattern->IsVariableProxy() || allow_harmony_for_in())) { 5035 for_info.parsing_result.declarations[0].pattern) ||
5036 allow_harmony_for_in())) {
5018 // Only increment the use count if we would have let this through 5037 // Only increment the use count if we would have let this through
5019 // without the flag. 5038 // without the flag.
5020 if (allow_harmony_for_in()) { 5039 if (allow_harmony_for_in()) {
5021 ++use_counts_[v8::Isolate::kForInInitializer]; 5040 impl()->CountUsage(v8::Isolate::kForInInitializer);
5022 } 5041 }
5023 ReportMessageAt(parsing_result.first_initializer_loc, 5042 impl()->ReportMessageAt(
5024 MessageTemplate::kForInOfLoopInitializer, 5043 for_info.parsing_result.first_initializer_loc,
5025 ForEachStatement::VisitModeString(mode)); 5044 MessageTemplate::kForInOfLoopInitializer,
5045 ForEachStatement::VisitModeString(for_info.mode));
5026 *ok = false; 5046 *ok = false;
5027 return nullptr; 5047 return impl()->NullStatement();
5028 } 5048 }
5029 5049
5030 Block* init_block = nullptr; 5050 BlockT init_block = impl()->RewriteForVarInLegacy(&for_info);
5031 bound_names_are_lexical =
5032 IsLexicalVariableMode(parsing_result.descriptor.mode);
5033 5051
5034 // special case for legacy for (var ... = ... in ...) 5052 auto loop =
marja 2016/09/20 19:36:30 I was thinking about the use of "auto" here (and b
nickie 2016/09/21 09:20:02 Yes, that's precisely what it does. (BTW, it's us
marja 2016/09/21 10:31:42 Ok, then it's fine.
5035 if (!bound_names_are_lexical && decl.pattern->IsVariableProxy() && 5053 factory()->NewForEachStatement(for_info.mode, labels, stmt_pos);
5036 decl.initializer != nullptr) { 5054 typename Types::Target target(this, loop);
5037 DCHECK(!allow_harmony_for_in());
5038 ++use_counts_[v8::Isolate::kForInInitializer];
5039 const AstRawString* name =
5040 decl.pattern->AsVariableProxy()->raw_name();
5041 VariableProxy* single_var = NewUnresolved(name);
5042 init_block = factory()->NewBlock(
5043 nullptr, 2, true, parsing_result.descriptor.declaration_pos);
5044 init_block->statements()->Add(
5045 factory()->NewExpressionStatement(
5046 factory()->NewAssignment(Token::ASSIGN, single_var,
5047 decl.initializer, kNoSourcePosition),
5048 kNoSourcePosition),
5049 zone());
5050 }
5051 5055
5052 // Rewrite a for-in/of statement of the form 5056 int each_keyword_pos = scanner()->location().beg_pos;
5053 //
5054 // for (let/const/var x in/of e) b
5055 //
5056 // into
5057 //
5058 // {
5059 // <let x' be a temporary variable>
5060 // for (x' in/of e) {
5061 // let/const/var x;
5062 // x = x';
5063 // b;
5064 // }
5065 // let x; // for TDZ
5066 // }
5067 5057
5068 Variable* temp = NewTemporary(ast_value_factory()->dot_for_string()); 5058 ExpressionT enumerable = impl()->EmptyExpression();
5069 ForEachStatement* loop = 5059 if (for_info.mode == ForEachStatement::ITERATE) {
5070 factory()->NewForEachStatement(mode, labels, stmt_pos);
5071 ParserTarget target(this, loop);
5072
5073 int each_keyword_position = scanner()->location().beg_pos;
5074
5075 Expression* enumerable;
5076 if (mode == ForEachStatement::ITERATE) {
5077 ExpressionClassifier classifier(this); 5060 ExpressionClassifier classifier(this);
5078 enumerable = ParseAssignmentExpression(true, CHECK_OK); 5061 enumerable = ParseAssignmentExpression(true, CHECK_OK);
5079 RewriteNonPattern(CHECK_OK); 5062 impl()->RewriteNonPattern(CHECK_OK);
5080 } else { 5063 } else {
5081 enumerable = ParseExpression(true, CHECK_OK); 5064 enumerable = ParseExpression(true, CHECK_OK);
5082 } 5065 }
5083 5066
5084 Expect(Token::RPAREN, CHECK_OK); 5067 Expect(Token::RPAREN, CHECK_OK);
5085 5068
5086 5069 StatementT final_loop = impl()->NullStatement();
5087 Block* body_block =
5088 factory()->NewBlock(NULL, 3, false, kNoSourcePosition);
5089
5090 Statement* final_loop;
5091 { 5070 {
5092 ReturnExprScope no_tail_calls(function_state_, 5071 ReturnExprScope no_tail_calls(function_state_,
5093 ReturnExprContext::kInsideForInOfBody); 5072 ReturnExprContext::kInsideForInOfBody);
5094 BlockState block_state(&scope_state_); 5073 BlockState block_state(&scope_state_);
5095 block_state.set_start_position(scanner()->location().beg_pos); 5074 block_state.set_start_position(scanner()->location().beg_pos);
5096 5075
5097 Statement* body = ParseScopedStatement(NULL, true, CHECK_OK); 5076 StatementT body = ParseScopedStatement(nullptr, true, CHECK_OK);
5098 5077
5099 auto each_initialization_block = 5078 std::pair<BlockT, ExpressionT> body_block_and_each_variable =
5100 factory()->NewBlock(nullptr, 1, true, kNoSourcePosition); 5079 impl()->DesugarBindingInForEachStatement(&for_info, CHECK_OK);
5101 { 5080 body_block_and_each_variable.first->statements()->Add(body, zone());
adamk 2016/09/20 16:34:31 Please create a variable for body_block, it'll mak
marja 2016/09/21 08:23:21 Why do we need the pair anyway, it looks like we'r
nickie 2016/09/21 09:20:02 After offline discussion, I'm removing the pair an
nickie 2016/09/21 09:20:02 See comment below.
5102 auto descriptor = parsing_result.descriptor; 5081 final_loop = impl()->InitializeForEachStatement(
5103 descriptor.declaration_pos = kNoSourcePosition; 5082 loop, body_block_and_each_variable.second, enumerable,
5104 descriptor.initialization_pos = kNoSourcePosition; 5083 body_block_and_each_variable.first, each_keyword_pos);
5105 decl.initializer = factory()->NewVariableProxy(temp);
5106 5084
5107 bool is_for_var_of =
5108 mode == ForEachStatement::ITERATE &&
5109 parsing_result.descriptor.mode == VariableMode::VAR;
5110
5111 PatternRewriter::DeclareAndInitializeVariables(
5112 this, each_initialization_block, &descriptor, &decl,
5113 bound_names_are_lexical || is_for_var_of ? &bound_names
5114 : nullptr,
5115 CHECK_OK);
5116
5117 // Annex B.3.5 prohibits the form
5118 // `try {} catch(e) { for (var e of {}); }`
5119 // So if we are parsing a statement like `for (var ... of ...)`
5120 // we need to walk up the scope chain and look for catch scopes
5121 // which have a simple binding, then compare their binding against
5122 // all of the names declared in the init of the for-of we're
5123 // parsing.
5124 if (is_for_var_of) {
5125 Scope* catch_scope = scope();
5126 while (catch_scope != nullptr &&
5127 !catch_scope->is_declaration_scope()) {
5128 if (catch_scope->is_catch_scope()) {
5129 auto name = catch_scope->catch_variable_name();
5130 if (name !=
5131 ast_value_factory()
5132 ->dot_catch_string()) { // i.e. is a simple binding
5133 if (bound_names.Contains(name)) {
5134 ReportMessageAt(parsing_result.bindings_loc,
5135 MessageTemplate::kVarRedeclaration, name);
5136 *ok = false;
5137 return nullptr;
5138 }
5139 }
5140 }
5141 catch_scope = catch_scope->outer_scope();
5142 }
5143 }
5144 }
5145
5146 body_block->statements()->Add(each_initialization_block, zone());
5147 body_block->statements()->Add(body, zone());
5148 VariableProxy* temp_proxy =
5149 factory()->NewVariableProxy(temp, each_beg_pos, each_end_pos);
5150 final_loop = InitializeForEachStatement(
5151 loop, temp_proxy, enumerable, body_block, each_keyword_position);
5152 block_state.set_end_position(scanner()->location().end_pos); 5085 block_state.set_end_position(scanner()->location().end_pos);
5153 body_block->set_scope(block_state.FinalizedBlockScope()); 5086 body_block_and_each_variable.first->set_scope(
5087 block_state.FinalizedBlockScope());
5154 } 5088 }
5155 5089
5156 // Create a TDZ for any lexically-bound names. 5090 init_block =
5157 if (bound_names_are_lexical) { 5091 impl()->CreateForEachStatementTDZ(init_block, &for_info, ok);
5158 DCHECK_NULL(init_block);
5159
5160 init_block =
5161 factory()->NewBlock(nullptr, 1, false, kNoSourcePosition);
5162
5163 for (int i = 0; i < bound_names.length(); ++i) {
5164 // TODO(adamk): This needs to be some sort of special
5165 // INTERNAL variable that's invisible to the debugger
5166 // but visible to everything else.
5167 Declaration* tdz_decl = DeclareVariable(
5168 bound_names[i], LET, kNoSourcePosition, CHECK_OK);
5169 tdz_decl->proxy()->var()->set_initializer_position(position());
5170 }
5171 }
5172 5092
5173 for_state.set_end_position(scanner()->location().end_pos); 5093 for_state.set_end_position(scanner()->location().end_pos);
5174 Scope* for_scope = for_state.FinalizedBlockScope(); 5094 Scope* for_scope = for_state.FinalizedBlockScope();
5175 // Parsed for-in loop w/ variable declarations. 5095 // Parsed for-in loop w/ variable declarations.
5176 if (init_block != nullptr) { 5096 if (!impl()->IsNullStatement(init_block)) {
5177 init_block->statements()->Add(final_loop, zone()); 5097 init_block->statements()->Add(final_loop, zone());
5178 init_block->set_scope(for_scope); 5098 init_block->set_scope(for_scope);
5179 return init_block; 5099 return init_block;
5180 } else { 5100 } else {
5181 DCHECK_NULL(for_scope); 5101 DCHECK_NULL(for_scope);
5182 return final_loop; 5102 return final_loop;
5183 } 5103 }
5184 } else { 5104 } else {
5185 bound_names_are_lexical = 5105 // One or more declaration not followed by in/of.
5186 IsLexicalVariableMode(parsing_result.descriptor.mode); 5106 init = impl()->BuildInitializationBlock(
5187 init = BuildInitializationBlock( 5107 &for_info.parsing_result,
5188 &parsing_result, bound_names_are_lexical ? &bound_names : nullptr, 5108 for_info.bound_names_are_lexical ? &for_info.bound_names : nullptr,
5189 CHECK_OK); 5109 CHECK_OK);
5190 } 5110 }
5191 } else { 5111 } else {
5112 // The initializer does not contain declarations.
5192 int lhs_beg_pos = peek_position(); 5113 int lhs_beg_pos = peek_position();
5193 ExpressionClassifier classifier(this); 5114 ExpressionClassifier classifier(this);
5194 Expression* expression = ParseExpressionCoverGrammar(false, CHECK_OK); 5115 ExpressionT expression = ParseExpressionCoverGrammar(false, CHECK_OK);
5195 int lhs_end_pos = scanner()->location().end_pos; 5116 int lhs_end_pos = scanner()->location().end_pos;
5196 ForEachStatement::VisitMode mode = ForEachStatement::ENUMERATE;
5197 5117
5198 bool is_for_each = CheckInOrOf(&mode); 5118 bool is_for_each = CheckInOrOf(&for_info.mode);
5199 bool is_destructuring = is_for_each && (expression->IsArrayLiteral() || 5119 bool is_destructuring = is_for_each && (expression->IsArrayLiteral() ||
5200 expression->IsObjectLiteral()); 5120 expression->IsObjectLiteral());
5201 5121
5202 if (is_destructuring) { 5122 if (is_destructuring) {
5203 ValidateAssignmentPattern(CHECK_OK); 5123 ValidateAssignmentPattern(CHECK_OK);
5204 } else { 5124 } else {
5205 RewriteNonPattern(CHECK_OK); 5125 impl()->RewriteNonPattern(CHECK_OK);
5206 } 5126 }
5207 5127
5208 if (is_for_each) { 5128 if (is_for_each) {
5129 // Initializer is reference followed by in/of.
5209 if (!is_destructuring) { 5130 if (!is_destructuring) {
5210 expression = CheckAndRewriteReferenceExpression( 5131 expression = impl()->CheckAndRewriteReferenceExpression(
5211 expression, lhs_beg_pos, lhs_end_pos, 5132 expression, lhs_beg_pos, lhs_end_pos,
5212 MessageTemplate::kInvalidLhsInFor, kSyntaxError, CHECK_OK); 5133 MessageTemplate::kInvalidLhsInFor, kSyntaxError, CHECK_OK);
5213 } 5134 }
5214 5135
5215 ForEachStatement* loop = 5136 auto loop =
5216 factory()->NewForEachStatement(mode, labels, stmt_pos); 5137 factory()->NewForEachStatement(for_info.mode, labels, stmt_pos);
5217 ParserTarget target(this, loop); 5138 typename Types::Target target(this, loop);
5218 5139
5219 int each_keyword_position = scanner()->location().beg_pos; 5140 int each_keyword_pos = scanner()->location().beg_pos;
5220 5141
5221 Expression* enumerable; 5142 ExpressionT enumerable = impl()->EmptyExpression();
5222 if (mode == ForEachStatement::ITERATE) { 5143 if (for_info.mode == ForEachStatement::ITERATE) {
5223 ExpressionClassifier classifier(this); 5144 ExpressionClassifier classifier(this);
5224 enumerable = ParseAssignmentExpression(true, CHECK_OK); 5145 enumerable = ParseAssignmentExpression(true, CHECK_OK);
5225 RewriteNonPattern(CHECK_OK); 5146 impl()->RewriteNonPattern(CHECK_OK);
5226 } else { 5147 } else {
5227 enumerable = ParseExpression(true, CHECK_OK); 5148 enumerable = ParseExpression(true, CHECK_OK);
5228 } 5149 }
5229 5150
5230 Expect(Token::RPAREN, CHECK_OK); 5151 Expect(Token::RPAREN, CHECK_OK);
5231 5152
5232 { 5153 {
5233 ReturnExprScope no_tail_calls(function_state_, 5154 ReturnExprScope no_tail_calls(function_state_,
5234 ReturnExprContext::kInsideForInOfBody); 5155 ReturnExprContext::kInsideForInOfBody);
5235 BlockState block_state(&scope_state_); 5156 BlockState block_state(&scope_state_);
5236 block_state.set_start_position(scanner()->location().beg_pos); 5157 block_state.set_start_position(scanner()->location().beg_pos);
5237 5158
5238 // For legacy compat reasons, give for loops similar treatment to 5159 // For legacy compat reasons, give for loops similar treatment to
5239 // if statements in allowing a function declaration for a body 5160 // if statements in allowing a function declaration for a body
5240 Statement* body = ParseScopedStatement(NULL, true, CHECK_OK); 5161 StatementT body = ParseScopedStatement(nullptr, true, CHECK_OK);
5241 block_state.set_end_position(scanner()->location().end_pos); 5162 block_state.set_end_position(scanner()->location().end_pos);
5242 Statement* final_loop = InitializeForEachStatement( 5163 StatementT final_loop = impl()->InitializeForEachStatement(
5243 loop, expression, enumerable, body, each_keyword_position); 5164 loop, expression, enumerable, body, each_keyword_pos);
5244 5165
5245 Scope* for_scope = for_state.FinalizedBlockScope(); 5166 Scope* for_scope = for_state.FinalizedBlockScope();
5246 DCHECK_NULL(for_scope); 5167 DCHECK_NULL(for_scope);
5247 USE(for_scope); 5168 USE(for_scope);
5248 Scope* block_scope = block_state.FinalizedBlockScope(); 5169 Scope* block_scope = block_state.FinalizedBlockScope();
5249 DCHECK_NULL(block_scope); 5170 DCHECK_NULL(block_scope);
5250 USE(block_scope); 5171 USE(block_scope);
5251 return final_loop; 5172 return final_loop;
5252 } 5173 }
5253 } else { 5174 } else {
5175 // Initializer is just an expression.
5254 init = factory()->NewExpressionStatement(expression, lhs_beg_pos); 5176 init = factory()->NewExpressionStatement(expression, lhs_beg_pos);
5255 } 5177 }
5256 } 5178 }
5257 } 5179 }
5258 5180
5259 // Standard 'for' loop 5181 // Standard 'for' loop, we have parsed the initializer at this point.
5260 ForStatement* loop = factory()->NewForStatement(labels, stmt_pos); 5182 auto loop = factory()->NewForStatement(labels, stmt_pos);
5261 ParserTarget target(this, loop); 5183 typename Types::Target target(this, loop);
5262 5184
5263 // Parsed initializer at this point.
5264 Expect(Token::SEMICOLON, CHECK_OK); 5185 Expect(Token::SEMICOLON, CHECK_OK);
5265 5186
5266 Expression* cond = NULL; 5187 ExpressionT cond = impl()->EmptyExpression();
5267 Statement* next = NULL; 5188 StatementT next = impl()->NullStatement();
5268 Statement* body = NULL; 5189 StatementT body = impl()->NullStatement();
5269 5190
5270 // If there are let bindings, then condition and the next statement of the 5191 // If there are let bindings, then condition and the next statement of the
5271 // for loop must be parsed in a new scope. 5192 // for loop must be parsed in a new scope.
5272 Scope* inner_scope = scope(); 5193 Scope* inner_scope = scope();
5273 // TODO(verwaest): Allocate this through a ScopeState as well. 5194 // TODO(verwaest): Allocate this through a ScopeState as well.
5274 if (bound_names_are_lexical && bound_names.length() > 0) { 5195 if (for_info.bound_names_are_lexical && for_info.bound_names.length() > 0) {
5275 inner_scope = NewScopeWithParent(inner_scope, BLOCK_SCOPE); 5196 inner_scope = NewScopeWithParent(inner_scope, BLOCK_SCOPE);
5276 inner_scope->set_start_position(scanner()->location().beg_pos); 5197 inner_scope->set_start_position(scanner()->location().beg_pos);
5277 } 5198 }
5278 { 5199 {
5279 BlockState block_state(&scope_state_, inner_scope); 5200 BlockState block_state(&scope_state_, inner_scope);
5280 5201
5281 if (peek() != Token::SEMICOLON) { 5202 if (peek() != Token::SEMICOLON) {
5282 cond = ParseExpression(true, CHECK_OK); 5203 cond = ParseExpression(true, CHECK_OK);
5283 } 5204 }
5284 Expect(Token::SEMICOLON, CHECK_OK); 5205 Expect(Token::SEMICOLON, CHECK_OK);
5285 5206
5286 if (peek() != Token::RPAREN) { 5207 if (peek() != Token::RPAREN) {
5287 Expression* exp = ParseExpression(true, CHECK_OK); 5208 ExpressionT exp = ParseExpression(true, CHECK_OK);
5288 next = factory()->NewExpressionStatement(exp, exp->position()); 5209 next = factory()->NewExpressionStatement(exp, exp->position());
5289 } 5210 }
5290 Expect(Token::RPAREN, CHECK_OK); 5211 Expect(Token::RPAREN, CHECK_OK);
5291 5212
5292 body = ParseScopedStatement(NULL, true, CHECK_OK); 5213 body = ParseScopedStatement(nullptr, true, CHECK_OK);
5293 } 5214 }
5294 5215
5295 Statement* result = NULL; 5216 if (for_info.bound_names_are_lexical && for_info.bound_names.length() > 0) {
5296 if (bound_names_are_lexical && bound_names.length() > 0) { 5217 auto result = impl()->DesugarLexicalBindingsInForStatement(
5297 result = DesugarLexicalBindingsInForStatement( 5218 loop, init, cond, next, body, inner_scope, &for_info, CHECK_OK);
5298 inner_scope, parsing_result.descriptor.mode, &bound_names, loop, init,
5299 cond, next, body, CHECK_OK);
5300 for_state.set_end_position(scanner()->location().end_pos); 5219 for_state.set_end_position(scanner()->location().end_pos);
5220 return result;
5301 } else { 5221 } else {
5302 for_state.set_end_position(scanner()->location().end_pos); 5222 for_state.set_end_position(scanner()->location().end_pos);
5303 Scope* for_scope = for_state.FinalizedBlockScope(); 5223 Scope* for_scope = for_state.FinalizedBlockScope();
5304 if (for_scope) { 5224 if (for_scope != nullptr) {
5305 // Rewrite a for statement of the form 5225 // Rewrite a for statement of the form
5306 // for (const x = i; c; n) b 5226 // for (const x = i; c; n) b
5307 // 5227 //
5308 // into 5228 // into
5309 // 5229 //
5310 // { 5230 // {
5311 // const x = i; 5231 // const x = i;
5312 // for (; c; n) b 5232 // for (; c; n) b
5313 // } 5233 // }
5314 // 5234 //
5315 // or, desugar 5235 // or, desugar
5316 // for (; c; n) b 5236 // for (; c; n) b
5317 // into 5237 // into
5318 // { 5238 // {
5319 // for (; c; n) b 5239 // for (; c; n) b
5320 // } 5240 // }
5321 // just in case b introduces a lexical binding some other way, e.g., if b 5241 // just in case b introduces a lexical binding some other way, e.g., if b
5322 // is a FunctionDeclaration. 5242 // is a FunctionDeclaration.
5323 Block* block = factory()->NewBlock(NULL, 2, false, kNoSourcePosition); 5243 BlockT block = factory()->NewBlock(NULL, 2, false, kNoSourcePosition);
5324 if (init != nullptr) { 5244 if (!impl()->IsNullStatement(init)) {
5325 block->statements()->Add(init, zone()); 5245 block->statements()->Add(init, zone());
5326 } 5246 }
5327 block->statements()->Add(loop, zone()); 5247 block->statements()->Add(loop, zone());
5328 block->set_scope(for_scope); 5248 block->set_scope(for_scope);
5329 loop->Initialize(NULL, cond, next, body); 5249 loop->Initialize(init, cond, next, body);
5330 result = block; 5250 return block;
5331 } else { 5251 } else {
5332 loop->Initialize(init, cond, next, body); 5252 loop->Initialize(init, cond, next, body);
5333 result = loop; 5253 return loop;
5334 } 5254 }
5335 } 5255 }
5336 return result;
5337 } 5256 }
5338 5257
5339 #undef CHECK_OK 5258 #undef CHECK_OK
5340 #undef CHECK_OK_CUSTOM 5259 #undef CHECK_OK_CUSTOM
5341 5260
5342 template <typename Impl> 5261 template <typename Impl>
5343 void ParserBase<Impl>::ObjectLiteralChecker::CheckDuplicateProto( 5262 void ParserBase<Impl>::ObjectLiteralChecker::CheckDuplicateProto(
5344 Token::Value property) { 5263 Token::Value property) {
5345 if (property == Token::SMI || property == Token::NUMBER) return; 5264 if (property == Token::SMI || property == Token::NUMBER) return;
5346 5265
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
5387 has_seen_constructor_ = true; 5306 has_seen_constructor_ = true;
5388 return; 5307 return;
5389 } 5308 }
5390 } 5309 }
5391 5310
5392 5311
5393 } // namespace internal 5312 } // namespace internal
5394 } // namespace v8 5313 } // namespace v8
5395 5314
5396 #endif // V8_PARSING_PARSER_BASE_H 5315 #endif // V8_PARSING_PARSER_BASE_H
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698