OLD | NEW |
---|---|
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/scopes.h" | 8 #include "src/ast/scopes.h" |
9 #include "src/bailout-reason.h" | 9 #include "src/bailout-reason.h" |
10 #include "src/hashmap.h" | 10 #include "src/hashmap.h" |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
183 | 183 |
184 struct DestructuringAssignment { | 184 struct DestructuringAssignment { |
185 public: | 185 public: |
186 DestructuringAssignment(ExpressionT expression, Scope* scope) | 186 DestructuringAssignment(ExpressionT expression, Scope* scope) |
187 : assignment(expression), scope(scope) {} | 187 : assignment(expression), scope(scope) {} |
188 | 188 |
189 ExpressionT assignment; | 189 ExpressionT assignment; |
190 Scope* scope; | 190 Scope* scope; |
191 }; | 191 }; |
192 | 192 |
193 struct TailCallExpression { | 193 class TailCallExpressionList { |
194 TailCallExpression(ExpressionT expression, int pos) | 194 public: |
195 : expression(expression), pos(pos) {} | 195 explicit TailCallExpressionList(Zone* zone) |
196 : zone_(zone), expressions_(0, zone) {} | |
196 | 197 |
197 ExpressionT expression; | 198 const ZoneList<ExpressionT>& expressions() const { return expressions_; } |
198 int pos; | 199 const Scanner::Location& location() const { return loc_; } |
200 | |
201 bool is_empty() const { return expressions_.is_empty(); } | |
202 | |
203 void Swap(TailCallExpressionList& other) { | |
204 expressions_.Swap(&other.expressions_); | |
205 std::swap(loc_, other.loc_); | |
206 } | |
207 | |
208 void Add(ExpressionT expr, const Scanner::Location& loc) { | |
209 if (expressions_.is_empty()) loc_ = loc; | |
210 expressions_.Add(expr, zone_); | |
211 } | |
212 | |
213 void Append(const TailCallExpressionList& other) { | |
214 if (expressions_.is_empty()) loc_ = other.loc_; | |
215 expressions_.AddAll(other.expressions_, zone_); | |
216 } | |
217 | |
218 private: | |
219 Zone* zone_; | |
220 ZoneList<ExpressionT> expressions_; | |
221 Scanner::Location loc_; | |
199 }; | 222 }; |
200 | 223 |
201 // Defines whether tail call expressions are allowed or not. | 224 // Defines whether tail call expressions are allowed or not. |
202 enum class ReturnExprContext { | 225 enum class ReturnExprContext { |
203 // Tail call expressions are allowed. | 226 // We are inside return statement which is allowed to contain tail call |
204 kNormal, | 227 // expressions. Tail call expressions are allowed. |
205 // Tail call expressions are not allowed. | 228 kInsideValidReturnStatement, |
229 | |
230 // We are inside a block in which tail call expressions are allowed but | |
231 // not yet inside a return statement. | |
232 kInsideValidBlock, | |
233 | |
234 // Tail call expressions are not allowed in the following blocks. | |
206 kInsideTryBlock, | 235 kInsideTryBlock, |
207 kInsideForInOfBody, | 236 kInsideForInOfBody, |
208 }; | 237 }; |
209 | 238 |
210 class FunctionState BASE_EMBEDDED { | 239 class FunctionState BASE_EMBEDDED { |
211 public: | 240 public: |
212 FunctionState(FunctionState** function_state_stack, Scope** scope_stack, | 241 FunctionState(FunctionState** function_state_stack, Scope** scope_stack, |
213 Scope* scope, FunctionKind kind, | 242 Scope* scope, FunctionKind kind, |
214 typename Traits::Type::Factory* factory); | 243 typename Traits::Type::Factory* factory); |
215 ~FunctionState(); | 244 ~FunctionState(); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
257 return generator_object_variable_; | 286 return generator_object_variable_; |
258 } | 287 } |
259 | 288 |
260 typename Traits::Type::Factory* factory() { return factory_; } | 289 typename Traits::Type::Factory* factory() { return factory_; } |
261 | 290 |
262 const List<DestructuringAssignment>& destructuring_assignments_to_rewrite() | 291 const List<DestructuringAssignment>& destructuring_assignments_to_rewrite() |
263 const { | 292 const { |
264 return destructuring_assignments_to_rewrite_; | 293 return destructuring_assignments_to_rewrite_; |
265 } | 294 } |
266 | 295 |
267 List<TailCallExpression>& expressions_in_tail_position() { | 296 TailCallExpressionList& tail_call_expressions() { |
268 return expressions_in_tail_position_; | 297 return tail_call_expressions_; |
269 } | 298 } |
270 void AddExpressionInTailPosition(ExpressionT expression, int pos) { | 299 void AddExpressionInTailPosition(ExpressionT expression, |
271 if (return_expr_context() == ReturnExprContext::kNormal) { | 300 const Scanner::Location& loc) { |
272 expressions_in_tail_position_.Add(TailCallExpression(expression, pos)); | 301 // If only FLAG_harmony_explicit_tailcalls is enabled then expression |
302 // must be a Call expression. | |
303 DCHECK(FLAG_harmony_tailcalls || !FLAG_harmony_explicit_tailcalls || | |
304 expression->IsCall()); | |
305 if (return_expr_context() == | |
306 ReturnExprContext::kInsideValidReturnStatement) { | |
307 tail_call_expressions_.Add(expression, loc); | |
273 } | 308 } |
274 } | 309 } |
275 | 310 |
276 ReturnExprContext return_expr_context() const { | 311 ReturnExprContext return_expr_context() const { |
277 return return_expr_context_; | 312 return return_expr_context_; |
278 } | 313 } |
279 void set_return_expr_context(ReturnExprContext context) { | 314 void set_return_expr_context(ReturnExprContext context) { |
280 return_expr_context_ = context; | 315 return_expr_context_ = context; |
281 } | 316 } |
282 | 317 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
325 // is used by yield expressions and return statements. It is not necessary | 360 // is used by yield expressions and return statements. It is not necessary |
326 // for generator functions to have this variable set. | 361 // for generator functions to have this variable set. |
327 Variable* generator_object_variable_; | 362 Variable* generator_object_variable_; |
328 | 363 |
329 FunctionState** function_state_stack_; | 364 FunctionState** function_state_stack_; |
330 FunctionState* outer_function_state_; | 365 FunctionState* outer_function_state_; |
331 Scope** scope_stack_; | 366 Scope** scope_stack_; |
332 Scope* outer_scope_; | 367 Scope* outer_scope_; |
333 | 368 |
334 List<DestructuringAssignment> destructuring_assignments_to_rewrite_; | 369 List<DestructuringAssignment> destructuring_assignments_to_rewrite_; |
335 List<TailCallExpression> expressions_in_tail_position_; | 370 TailCallExpressionList tail_call_expressions_; |
336 ReturnExprContext return_expr_context_; | 371 ReturnExprContext return_expr_context_; |
337 ZoneList<ExpressionT> non_patterns_to_rewrite_; | 372 ZoneList<ExpressionT> non_patterns_to_rewrite_; |
338 | 373 |
339 typename Traits::Type::Factory* factory_; | 374 typename Traits::Type::Factory* factory_; |
340 | 375 |
341 // If true, the next (and immediately following) function literal is | 376 // If true, the next (and immediately following) function literal is |
342 // preceded by a parenthesis. | 377 // preceded by a parenthesis. |
343 bool next_function_is_parenthesized_; | 378 bool next_function_is_parenthesized_; |
344 | 379 |
345 // The value of the parents' next_function_is_parenthesized_, as it applies | 380 // The value of the parents' next_function_is_parenthesized_, as it applies |
346 // to this function. Filled in by constructor. | 381 // to this function. Filled in by constructor. |
347 bool this_function_is_parenthesized_; | 382 bool this_function_is_parenthesized_; |
348 | 383 |
349 friend class ParserTraits; | 384 friend class ParserTraits; |
350 friend class PreParserTraits; | 385 friend class PreParserTraits; |
351 friend class Checkpoint; | 386 friend class Checkpoint; |
352 }; | 387 }; |
353 | 388 |
354 // This scope sets current ReturnExprContext to given value. | 389 // This scope sets current ReturnExprContext to given value. |
355 class ReturnExprScope { | 390 class ReturnExprScope { |
356 public: | 391 public: |
357 explicit ReturnExprScope(FunctionState* function_state, | 392 explicit ReturnExprScope(FunctionState* function_state, |
358 ReturnExprContext return_expr_context) | 393 ReturnExprContext return_expr_context) |
359 : function_state_(function_state), | 394 : function_state_(function_state), |
360 sav_return_expr_context_(function_state->return_expr_context()) { | 395 sav_return_expr_context_(function_state->return_expr_context()) { |
361 function_state->set_return_expr_context(return_expr_context); | 396 // Don't update context if we are requested to enable tail call |
397 // expressions but current block does not allow them. | |
398 if (return_expr_context != | |
399 ReturnExprContext::kInsideValidReturnStatement || | |
400 sav_return_expr_context_ == ReturnExprContext::kInsideValidBlock) { | |
401 function_state->set_return_expr_context(return_expr_context); | |
402 } | |
362 } | 403 } |
363 ~ReturnExprScope() { | 404 ~ReturnExprScope() { |
364 function_state_->set_return_expr_context(sav_return_expr_context_); | 405 function_state_->set_return_expr_context(sav_return_expr_context_); |
365 } | 406 } |
366 | 407 |
367 private: | 408 private: |
368 FunctionState* function_state_; | 409 FunctionState* function_state_; |
369 ReturnExprContext sav_return_expr_context_; | 410 ReturnExprContext sav_return_expr_context_; |
370 }; | 411 }; |
371 | 412 |
372 // Collects all return expressions at tail call position in this scope | 413 // Collects all return expressions at tail call position in this scope |
373 // to a separate list. | 414 // to a separate list. |
374 class CollectExpressionsInTailPositionToListScope { | 415 class CollectExpressionsInTailPositionToListScope { |
375 public: | 416 public: |
376 CollectExpressionsInTailPositionToListScope(FunctionState* function_state, | 417 CollectExpressionsInTailPositionToListScope(FunctionState* function_state, |
377 List<TailCallExpression>* list) | 418 TailCallExpressionList* list) |
378 : function_state_(function_state), list_(list) { | 419 : function_state_(function_state), list_(list) { |
379 function_state->expressions_in_tail_position().Swap(list_); | 420 function_state->tail_call_expressions().Swap(*list_); |
380 } | 421 } |
381 ~CollectExpressionsInTailPositionToListScope() { | 422 ~CollectExpressionsInTailPositionToListScope() { |
382 function_state_->expressions_in_tail_position().Swap(list_); | 423 function_state_->tail_call_expressions().Swap(*list_); |
383 } | 424 } |
384 | 425 |
385 private: | 426 private: |
386 FunctionState* function_state_; | 427 FunctionState* function_state_; |
387 List<TailCallExpression>* list_; | 428 TailCallExpressionList* list_; |
388 }; | 429 }; |
389 | 430 |
390 // Annoyingly, arrow functions first parse as comma expressions, then when we | 431 // Annoyingly, arrow functions first parse as comma expressions, then when we |
391 // see the => we have to go back and reinterpret the arguments as being formal | 432 // see the => we have to go back and reinterpret the arguments as being formal |
392 // parameters. To do so we need to reset some of the parser state back to | 433 // parameters. To do so we need to reset some of the parser state back to |
393 // what it was before the arguments were first seen. | 434 // what it was before the arguments were first seen. |
394 class Checkpoint BASE_EMBEDDED { | 435 class Checkpoint BASE_EMBEDDED { |
395 public: | 436 public: |
396 explicit Checkpoint(ParserBase* parser) { | 437 explicit Checkpoint(ParserBase* parser) { |
397 function_state_ = parser->function_state_; | 438 function_state_ = parser->function_state_; |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
635 Traits::ReportMessageAt(source_location, message, arg, error_type); | 676 Traits::ReportMessageAt(source_location, message, arg, error_type); |
636 } | 677 } |
637 | 678 |
638 void ReportMessageAt(Scanner::Location location, | 679 void ReportMessageAt(Scanner::Location location, |
639 MessageTemplate::Template message, | 680 MessageTemplate::Template message, |
640 ParseErrorType error_type = kSyntaxError) { | 681 ParseErrorType error_type = kSyntaxError) { |
641 Traits::ReportMessageAt(location, message, reinterpret_cast<const char*>(0), | 682 Traits::ReportMessageAt(location, message, reinterpret_cast<const char*>(0), |
642 error_type); | 683 error_type); |
643 } | 684 } |
644 | 685 |
645 void ReportIllegalTailCallAt(int pos, ReturnExprContext return_expr_context) { | |
646 Scanner::Location loc(pos, pos + 1); | |
647 MessageTemplate::Template msg = MessageTemplate::kNone; | |
648 switch (return_expr_context) { | |
649 case ReturnExprContext::kNormal: | |
650 UNREACHABLE(); | |
651 return; | |
652 case ReturnExprContext::kInsideTryBlock: | |
653 msg = MessageTemplate::kTailCallInTryBlock; | |
654 break; | |
655 case ReturnExprContext::kInsideForInOfBody: | |
656 msg = MessageTemplate::kTailCallInForInOf; | |
657 break; | |
658 } | |
659 ReportMessageAt(loc, msg); | |
660 } | |
661 | |
662 void GetUnexpectedTokenMessage( | 686 void GetUnexpectedTokenMessage( |
663 Token::Value token, MessageTemplate::Template* message, | 687 Token::Value token, MessageTemplate::Template* message, |
664 Scanner::Location* location, const char** arg, | 688 Scanner::Location* location, const char** arg, |
665 MessageTemplate::Template default_ = MessageTemplate::kUnexpectedToken); | 689 MessageTemplate::Template default_ = MessageTemplate::kUnexpectedToken); |
666 | 690 |
667 void ReportUnexpectedToken(Token::Value token); | 691 void ReportUnexpectedToken(Token::Value token); |
668 void ReportUnexpectedTokenAt( | 692 void ReportUnexpectedTokenAt( |
669 Scanner::Location location, Token::Value token, | 693 Scanner::Location location, Token::Value token, |
670 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken); | 694 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken); |
671 | 695 |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
752 } | 776 } |
753 } | 777 } |
754 | 778 |
755 void ValidateLetPattern(const ExpressionClassifier* classifier, bool* ok) { | 779 void ValidateLetPattern(const ExpressionClassifier* classifier, bool* ok) { |
756 if (!classifier->is_valid_let_pattern()) { | 780 if (!classifier->is_valid_let_pattern()) { |
757 ReportClassifierError(classifier->let_pattern_error()); | 781 ReportClassifierError(classifier->let_pattern_error()); |
758 *ok = false; | 782 *ok = false; |
759 } | 783 } |
760 } | 784 } |
761 | 785 |
786 void ValidateTailCallExpression(const ExpressionClassifier* classifier, | |
787 bool* ok) { | |
788 if (FLAG_harmony_explicit_tailcalls && | |
789 classifier->has_tail_call_expression()) { | |
rossberg
2016/05/02 10:59:40
I'm confused, why is it an error if it _has_ a tai
Igor Sheludko
2016/05/04 10:28:55
Updated confusing function name.
| |
790 ReportClassifierError(classifier->tail_call_expression_error()); | |
791 *ok = false; | |
792 } | |
793 } | |
794 | |
762 void ExpressionUnexpectedToken(ExpressionClassifier* classifier) { | 795 void ExpressionUnexpectedToken(ExpressionClassifier* classifier) { |
763 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken; | 796 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken; |
764 const char* arg; | 797 const char* arg; |
765 Scanner::Location location = scanner()->peek_location(); | 798 Scanner::Location location = scanner()->peek_location(); |
766 GetUnexpectedTokenMessage(peek(), &message, &location, &arg); | 799 GetUnexpectedTokenMessage(peek(), &message, &location, &arg); |
767 classifier->RecordExpressionError(location, message, arg); | 800 classifier->RecordExpressionError(location, message, arg); |
768 } | 801 } |
769 | 802 |
770 void BindingPatternUnexpectedToken(ExpressionClassifier* classifier) { | 803 void BindingPatternUnexpectedToken(ExpressionClassifier* classifier) { |
771 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken; | 804 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken; |
(...skipping 13 matching lines...) Expand all Loading... | |
785 | 818 |
786 void FormalParameterInitializerUnexpectedToken( | 819 void FormalParameterInitializerUnexpectedToken( |
787 ExpressionClassifier* classifier) { | 820 ExpressionClassifier* classifier) { |
788 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken; | 821 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken; |
789 const char* arg; | 822 const char* arg; |
790 Scanner::Location location = scanner()->peek_location(); | 823 Scanner::Location location = scanner()->peek_location(); |
791 GetUnexpectedTokenMessage(peek(), &message, &location, &arg); | 824 GetUnexpectedTokenMessage(peek(), &message, &location, &arg); |
792 classifier->RecordFormalParameterInitializerError(location, message, arg); | 825 classifier->RecordFormalParameterInitializerError(location, message, arg); |
793 } | 826 } |
794 | 827 |
828 enum AcceptTailCallExpression { kDontAcceptTCE, kAcceptTCE }; | |
829 | |
795 // Recursive descent functions: | 830 // Recursive descent functions: |
796 | 831 |
797 // Parses an identifier that is valid for the current scope, in particular it | 832 // Parses an identifier that is valid for the current scope, in particular it |
798 // fails on strict mode future reserved keywords in a strict scope. If | 833 // fails on strict mode future reserved keywords in a strict scope. If |
799 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or | 834 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or |
800 // "arguments" as identifier even in strict mode (this is needed in cases like | 835 // "arguments" as identifier even in strict mode (this is needed in cases like |
801 // "var foo = eval;"). | 836 // "var foo = eval;"). |
802 IdentifierT ParseIdentifier(AllowRestrictedIdentifiers, bool* ok); | 837 IdentifierT ParseIdentifier(AllowRestrictedIdentifiers, bool* ok); |
803 IdentifierT ParseAndClassifyIdentifier(ExpressionClassifier* classifier, | 838 IdentifierT ParseAndClassifyIdentifier(ExpressionClassifier* classifier, |
804 bool* ok); | 839 bool* ok); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
838 ExpressionClassifier* classifier, IdentifierT* name, bool* ok); | 873 ExpressionClassifier* classifier, IdentifierT* name, bool* ok); |
839 typename Traits::Type::ExpressionList ParseArguments( | 874 typename Traits::Type::ExpressionList ParseArguments( |
840 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier, | 875 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier, |
841 bool* ok); | 876 bool* ok); |
842 | 877 |
843 ExpressionT ParseAssignmentExpression(bool accept_IN, | 878 ExpressionT ParseAssignmentExpression(bool accept_IN, |
844 ExpressionClassifier* classifier, | 879 ExpressionClassifier* classifier, |
845 bool* ok); | 880 bool* ok); |
846 ExpressionT ParseYieldExpression(bool accept_IN, | 881 ExpressionT ParseYieldExpression(bool accept_IN, |
847 ExpressionClassifier* classifier, bool* ok); | 882 ExpressionClassifier* classifier, bool* ok); |
883 ExpressionT ParseTailCallExpression(ExpressionClassifier* classifier, | |
884 bool* ok); | |
848 ExpressionT ParseConditionalExpression(bool accept_IN, | 885 ExpressionT ParseConditionalExpression(bool accept_IN, |
849 ExpressionClassifier* classifier, | 886 ExpressionClassifier* classifier, |
850 bool* ok); | 887 bool* ok); |
851 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, | 888 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, |
852 ExpressionClassifier* classifier, bool* ok); | 889 ExpressionClassifier* classifier, bool* ok); |
853 ExpressionT ParseUnaryExpression(ExpressionClassifier* classifier, bool* ok); | 890 ExpressionT ParseUnaryExpression(ExpressionClassifier* classifier, bool* ok); |
854 ExpressionT ParsePostfixExpression(ExpressionClassifier* classifier, | 891 ExpressionT ParsePostfixExpression(ExpressionClassifier* classifier, |
855 bool* ok); | 892 bool* ok); |
856 ExpressionT ParseLeftHandSideExpression(ExpressionClassifier* classifier, | 893 ExpressionT ParseLeftHandSideExpression(AcceptTailCallExpression accept_TCE, |
894 ExpressionClassifier* classifier, | |
857 bool* ok); | 895 bool* ok); |
858 ExpressionT ParseMemberWithNewPrefixesExpression( | 896 ExpressionT ParseMemberWithNewPrefixesExpression( |
859 ExpressionClassifier* classifier, bool* ok); | 897 ExpressionClassifier* classifier, bool* ok); |
860 ExpressionT ParseMemberExpression(ExpressionClassifier* classifier, bool* ok); | 898 ExpressionT ParseMemberExpression(ExpressionClassifier* classifier, bool* ok); |
861 ExpressionT ParseMemberExpressionContinuation( | 899 ExpressionT ParseMemberExpressionContinuation( |
862 ExpressionT expression, ExpressionClassifier* classifier, bool* ok); | 900 ExpressionT expression, ExpressionClassifier* classifier, bool* ok); |
863 ExpressionT ParseArrowFunctionLiteral(bool accept_IN, | 901 ExpressionT ParseArrowFunctionLiteral(bool accept_IN, |
864 const FormalParametersT& parameters, | 902 const FormalParametersT& parameters, |
865 const ExpressionClassifier& classifier, | 903 const ExpressionClassifier& classifier, |
866 bool* ok); | 904 bool* ok); |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1009 expected_property_count_(0), | 1047 expected_property_count_(0), |
1010 this_location_(Scanner::Location::invalid()), | 1048 this_location_(Scanner::Location::invalid()), |
1011 return_location_(Scanner::Location::invalid()), | 1049 return_location_(Scanner::Location::invalid()), |
1012 super_location_(Scanner::Location::invalid()), | 1050 super_location_(Scanner::Location::invalid()), |
1013 kind_(kind), | 1051 kind_(kind), |
1014 generator_object_variable_(NULL), | 1052 generator_object_variable_(NULL), |
1015 function_state_stack_(function_state_stack), | 1053 function_state_stack_(function_state_stack), |
1016 outer_function_state_(*function_state_stack), | 1054 outer_function_state_(*function_state_stack), |
1017 scope_stack_(scope_stack), | 1055 scope_stack_(scope_stack), |
1018 outer_scope_(*scope_stack), | 1056 outer_scope_(*scope_stack), |
1019 return_expr_context_(ReturnExprContext::kNormal), | 1057 tail_call_expressions_(scope->zone()), |
1058 return_expr_context_(ReturnExprContext::kInsideValidBlock), | |
1020 non_patterns_to_rewrite_(0, scope->zone()), | 1059 non_patterns_to_rewrite_(0, scope->zone()), |
1021 factory_(factory), | 1060 factory_(factory), |
1022 next_function_is_parenthesized_(false), | 1061 next_function_is_parenthesized_(false), |
1023 this_function_is_parenthesized_(false) { | 1062 this_function_is_parenthesized_(false) { |
1024 *scope_stack_ = scope; | 1063 *scope_stack_ = scope; |
1025 *function_state_stack = this; | 1064 *function_state_stack = this; |
1026 if (outer_function_state_) { | 1065 if (outer_function_state_) { |
1027 this_function_is_parenthesized_ = | 1066 this_function_is_parenthesized_ = |
1028 outer_function_state_->next_function_is_parenthesized_; | 1067 outer_function_state_->next_function_is_parenthesized_; |
1029 outer_function_state_->next_function_is_parenthesized_ = false; | 1068 outer_function_state_->next_function_is_parenthesized_ = false; |
(...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1449 | 1488 |
1450 template <class Traits> | 1489 template <class Traits> |
1451 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( | 1490 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( |
1452 bool accept_IN, bool* ok) { | 1491 bool accept_IN, bool* ok) { |
1453 ExpressionClassifier classifier(this); | 1492 ExpressionClassifier classifier(this); |
1454 ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK); | 1493 ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK); |
1455 Traits::RewriteNonPattern(&classifier, CHECK_OK); | 1494 Traits::RewriteNonPattern(&classifier, CHECK_OK); |
1456 return result; | 1495 return result; |
1457 } | 1496 } |
1458 | 1497 |
1459 | |
1460 template <class Traits> | 1498 template <class Traits> |
1461 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( | 1499 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( |
1462 bool accept_IN, ExpressionClassifier* classifier, bool* ok) { | 1500 bool accept_IN, ExpressionClassifier* classifier, bool* ok) { |
1463 // Expression :: | 1501 // Expression :: |
1464 // AssignmentExpression | 1502 // AssignmentExpression |
1465 // Expression ',' AssignmentExpression | 1503 // Expression ',' AssignmentExpression |
1466 | 1504 |
1467 ExpressionClassifier binding_classifier(this); | 1505 ExpressionClassifier binding_classifier(this); |
1468 ExpressionT result = | 1506 ExpressionT result = |
1469 this->ParseAssignmentExpression(accept_IN, &binding_classifier, CHECK_OK); | 1507 this->ParseAssignmentExpression(accept_IN, &binding_classifier, CHECK_OK); |
1470 classifier->Accumulate(&binding_classifier, | 1508 classifier->Accumulate(&binding_classifier, |
1471 ExpressionClassifier::AllProductions); | 1509 ExpressionClassifier::AllProductions); |
1472 bool is_simple_parameter_list = this->IsIdentifier(result); | 1510 bool is_simple_parameter_list = this->IsIdentifier(result); |
1473 bool seen_rest = false; | 1511 bool seen_rest = false; |
1474 while (peek() == Token::COMMA) { | 1512 while (peek() == Token::COMMA) { |
1513 ValidateTailCallExpression(classifier, CHECK_OK); | |
1475 if (seen_rest) { | 1514 if (seen_rest) { |
1476 // At this point the production can't possibly be valid, but we don't know | 1515 // At this point the production can't possibly be valid, but we don't know |
1477 // which error to signal. | 1516 // which error to signal. |
1478 classifier->RecordArrowFormalParametersError( | 1517 classifier->RecordArrowFormalParametersError( |
1479 scanner()->peek_location(), MessageTemplate::kParamAfterRest); | 1518 scanner()->peek_location(), MessageTemplate::kParamAfterRest); |
1480 } | 1519 } |
1481 Consume(Token::COMMA); | 1520 Consume(Token::COMMA); |
1482 bool is_rest = false; | 1521 bool is_rest = false; |
1483 if (peek() == Token::ELLIPSIS) { | 1522 if (peek() == Token::ELLIPSIS) { |
1484 // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only | 1523 // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only |
(...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1956 template <class Traits> | 1995 template <class Traits> |
1957 typename ParserBase<Traits>::ExpressionT | 1996 typename ParserBase<Traits>::ExpressionT |
1958 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, | 1997 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, |
1959 ExpressionClassifier* classifier, | 1998 ExpressionClassifier* classifier, |
1960 bool* ok) { | 1999 bool* ok) { |
1961 // AssignmentExpression :: | 2000 // AssignmentExpression :: |
1962 // ConditionalExpression | 2001 // ConditionalExpression |
1963 // ArrowFunction | 2002 // ArrowFunction |
1964 // YieldExpression | 2003 // YieldExpression |
1965 // LeftHandSideExpression AssignmentOperator AssignmentExpression | 2004 // LeftHandSideExpression AssignmentOperator AssignmentExpression |
1966 // TailCallExpression | |
1967 bool is_destructuring_assignment = false; | 2005 bool is_destructuring_assignment = false; |
1968 int lhs_beg_pos = peek_position(); | 2006 int lhs_beg_pos = peek_position(); |
1969 | 2007 |
1970 if (peek() == Token::YIELD && is_generator()) { | 2008 if (peek() == Token::YIELD && is_generator()) { |
1971 return this->ParseYieldExpression(accept_IN, classifier, ok); | 2009 return this->ParseYieldExpression(accept_IN, classifier, ok); |
1972 } | 2010 } |
1973 | 2011 |
1974 FuncNameInferrer::State fni_state(fni_); | 2012 FuncNameInferrer::State fni_state(fni_); |
1975 ParserBase<Traits>::Checkpoint checkpoint(this); | 2013 ParserBase<Traits>::Checkpoint checkpoint(this); |
1976 ExpressionClassifier arrow_formals_classifier(this, | 2014 ExpressionClassifier arrow_formals_classifier(this, |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2157 } | 2195 } |
2158 | 2196 |
2159 expression = Traits::BuildIteratorResult(expression, false); | 2197 expression = Traits::BuildIteratorResult(expression, false); |
2160 // Hackily disambiguate o from o.next and o [Symbol.iterator](). | 2198 // Hackily disambiguate o from o.next and o [Symbol.iterator](). |
2161 // TODO(verwaest): Come up with a better solution. | 2199 // TODO(verwaest): Come up with a better solution. |
2162 typename Traits::Type::YieldExpression yield = | 2200 typename Traits::Type::YieldExpression yield = |
2163 factory()->NewYield(generator_object, expression, pos); | 2201 factory()->NewYield(generator_object, expression, pos); |
2164 return yield; | 2202 return yield; |
2165 } | 2203 } |
2166 | 2204 |
2205 template <class Traits> | |
2206 typename ParserBase<Traits>::ExpressionT | |
2207 ParserBase<Traits>::ParseTailCallExpression(ExpressionClassifier* classifier, | |
2208 bool* ok) { | |
2209 // TailCallExpression:: | |
2210 // 'continue' MemberExpression Arguments | |
2211 // 'continue' CallExpression Arguments | |
2212 // 'continue' MemberExpression TemplateLiteral | |
2213 // 'continue' CallExpression TemplateLiteral | |
2214 Expect(Token::CONTINUE, CHECK_OK); | |
2215 int pos = position(); | |
2216 int sub_expression_pos = peek_position(); | |
2217 ExpressionT expression = | |
2218 this->ParseLeftHandSideExpression(kDontAcceptTCE, classifier, ok); | |
2219 Scanner::Location loc(pos, scanner()->location().end_pos); | |
2220 ReturnExprContext return_expr_context = | |
2221 function_state_->return_expr_context(); | |
2222 if (return_expr_context != ReturnExprContext::kInsideValidReturnStatement) { | |
2223 MessageTemplate::Template msg = MessageTemplate::kNone; | |
2224 switch (return_expr_context) { | |
2225 case ReturnExprContext::kInsideValidReturnStatement: | |
2226 UNREACHABLE(); | |
2227 return Traits::EmptyExpression(); | |
2228 case ReturnExprContext::kInsideValidBlock: | |
2229 msg = MessageTemplate::kUnexpectedTailCall; | |
2230 break; | |
2231 case ReturnExprContext::kInsideTryBlock: | |
2232 msg = MessageTemplate::kUnexpectedTailCallInTryBlock; | |
2233 break; | |
2234 case ReturnExprContext::kInsideForInOfBody: | |
2235 msg = MessageTemplate::kUnexpectedTailCallInForInOf; | |
2236 break; | |
2237 } | |
2238 ReportMessageAt(loc, msg); | |
2239 *ok = false; | |
2240 return Traits::EmptyExpression(); | |
2241 } | |
2242 if (!expression->IsCall()) { | |
2243 Scanner::Location sub_loc(sub_expression_pos, loc.end_pos); | |
2244 ReportMessageAt(sub_loc, MessageTemplate::kUnexpectedInsideTailCall); | |
2245 *ok = false; | |
2246 return Traits::EmptyExpression(); | |
2247 } | |
2248 classifier->RecordTailCallExpressionError( | |
2249 loc, MessageTemplate::kUnexpectedTailCall); | |
2250 function_state_->AddExpressionInTailPosition(expression, loc); | |
2251 return expression; | |
2252 } | |
2167 | 2253 |
2168 // Precedence = 3 | 2254 // Precedence = 3 |
2169 template <class Traits> | 2255 template <class Traits> |
2170 typename ParserBase<Traits>::ExpressionT | 2256 typename ParserBase<Traits>::ExpressionT |
2171 ParserBase<Traits>::ParseConditionalExpression(bool accept_IN, | 2257 ParserBase<Traits>::ParseConditionalExpression(bool accept_IN, |
2172 ExpressionClassifier* classifier, | 2258 ExpressionClassifier* classifier, |
2173 bool* ok) { | 2259 bool* ok) { |
2174 // ConditionalExpression :: | 2260 // ConditionalExpression :: |
2175 // LogicalOrExpression | 2261 // LogicalOrExpression |
2176 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression | 2262 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression |
(...skipping 24 matching lines...) Expand all Loading... | |
2201 template <class Traits> | 2287 template <class Traits> |
2202 typename ParserBase<Traits>::ExpressionT | 2288 typename ParserBase<Traits>::ExpressionT |
2203 ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN, | 2289 ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN, |
2204 ExpressionClassifier* classifier, | 2290 ExpressionClassifier* classifier, |
2205 bool* ok) { | 2291 bool* ok) { |
2206 DCHECK(prec >= 4); | 2292 DCHECK(prec >= 4); |
2207 ExpressionT x = this->ParseUnaryExpression(classifier, CHECK_OK); | 2293 ExpressionT x = this->ParseUnaryExpression(classifier, CHECK_OK); |
2208 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { | 2294 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { |
2209 // prec1 >= 4 | 2295 // prec1 >= 4 |
2210 while (Precedence(peek(), accept_IN) == prec1) { | 2296 while (Precedence(peek(), accept_IN) == prec1) { |
2297 ValidateTailCallExpression(classifier, CHECK_OK); | |
rossberg
2016/05/02 10:59:40
Ah, okay, think I get it now: this is validating t
Igor Sheludko
2016/05/04 10:28:55
Done.
| |
2211 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2298 Traits::RewriteNonPattern(classifier, CHECK_OK); |
2212 BindingPatternUnexpectedToken(classifier); | 2299 BindingPatternUnexpectedToken(classifier); |
2213 ArrowFormalParametersUnexpectedToken(classifier); | 2300 ArrowFormalParametersUnexpectedToken(classifier); |
2214 Token::Value op = Next(); | 2301 Token::Value op = Next(); |
2215 int pos = position(); | 2302 int pos = position(); |
2216 | 2303 |
2217 const bool is_right_associative = op == Token::EXP; | 2304 const bool is_right_associative = op == Token::EXP; |
2218 const int next_prec = is_right_associative ? prec1 : prec1 + 1; | 2305 const int next_prec = is_right_associative ? prec1 : prec1 + 1; |
2219 ExpressionT y = | 2306 ExpressionT y = |
2220 ParseBinaryExpression(next_prec, accept_IN, classifier, CHECK_OK); | 2307 ParseBinaryExpression(next_prec, accept_IN, classifier, CHECK_OK); |
2308 if (op != Token::OR && op != Token::AND) { | |
2309 ValidateTailCallExpression(classifier, CHECK_OK); | |
2310 } | |
2221 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2311 Traits::RewriteNonPattern(classifier, CHECK_OK); |
2222 | 2312 |
2223 if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos, | 2313 if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos, |
2224 factory())) { | 2314 factory())) { |
2225 continue; | 2315 continue; |
2226 } | 2316 } |
2227 | 2317 |
2228 // For now we distinguish between comparisons and other binary | 2318 // For now we distinguish between comparisons and other binary |
2229 // operations. (We could combine the two and get rid of this | 2319 // operations. (We could combine the two and get rid of this |
2230 // code and AST node eventually.) | 2320 // code and AST node eventually.) |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2326 | 2416 |
2327 template <class Traits> | 2417 template <class Traits> |
2328 typename ParserBase<Traits>::ExpressionT | 2418 typename ParserBase<Traits>::ExpressionT |
2329 ParserBase<Traits>::ParsePostfixExpression(ExpressionClassifier* classifier, | 2419 ParserBase<Traits>::ParsePostfixExpression(ExpressionClassifier* classifier, |
2330 bool* ok) { | 2420 bool* ok) { |
2331 // PostfixExpression :: | 2421 // PostfixExpression :: |
2332 // LeftHandSideExpression ('++' | '--')? | 2422 // LeftHandSideExpression ('++' | '--')? |
2333 | 2423 |
2334 int lhs_beg_pos = peek_position(); | 2424 int lhs_beg_pos = peek_position(); |
2335 ExpressionT expression = | 2425 ExpressionT expression = |
2336 this->ParseLeftHandSideExpression(classifier, CHECK_OK); | 2426 this->ParseLeftHandSideExpression(kAcceptTCE, classifier, CHECK_OK); |
2337 if (!scanner()->HasAnyLineTerminatorBeforeNext() && | 2427 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
2338 Token::IsCountOp(peek())) { | 2428 Token::IsCountOp(peek())) { |
2339 BindingPatternUnexpectedToken(classifier); | 2429 BindingPatternUnexpectedToken(classifier); |
2340 ArrowFormalParametersUnexpectedToken(classifier); | 2430 ArrowFormalParametersUnexpectedToken(classifier); |
2341 | 2431 |
2342 expression = this->CheckAndRewriteReferenceExpression( | 2432 expression = this->CheckAndRewriteReferenceExpression( |
2343 expression, lhs_beg_pos, scanner()->location().end_pos, | 2433 expression, lhs_beg_pos, scanner()->location().end_pos, |
2344 MessageTemplate::kInvalidLhsInPostfixOp, CHECK_OK); | 2434 MessageTemplate::kInvalidLhsInPostfixOp, CHECK_OK); |
2345 expression = this->MarkExpressionAsAssigned(expression); | 2435 expression = this->MarkExpressionAsAssigned(expression); |
2346 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2436 Traits::RewriteNonPattern(classifier, CHECK_OK); |
2347 | 2437 |
2348 Token::Value next = Next(); | 2438 Token::Value next = Next(); |
2349 expression = | 2439 expression = |
2350 factory()->NewCountOperation(next, | 2440 factory()->NewCountOperation(next, |
2351 false /* postfix */, | 2441 false /* postfix */, |
2352 expression, | 2442 expression, |
2353 position()); | 2443 position()); |
2354 } | 2444 } |
2355 return expression; | 2445 return expression; |
2356 } | 2446 } |
2357 | 2447 |
2358 | |
2359 template <class Traits> | 2448 template <class Traits> |
2360 typename ParserBase<Traits>::ExpressionT | 2449 typename ParserBase<Traits>::ExpressionT |
2361 ParserBase<Traits>::ParseLeftHandSideExpression( | 2450 ParserBase<Traits>::ParseLeftHandSideExpression( |
2362 ExpressionClassifier* classifier, bool* ok) { | 2451 AcceptTailCallExpression accept_TCE, ExpressionClassifier* classifier, |
2452 bool* ok) { | |
2363 // LeftHandSideExpression :: | 2453 // LeftHandSideExpression :: |
2364 // (NewExpression | MemberExpression) ... | 2454 // (NewExpression | MemberExpression) ... |
2365 | 2455 |
2456 if (FLAG_harmony_explicit_tailcalls && accept_TCE == kAcceptTCE && | |
2457 peek() == Token::CONTINUE) { | |
2458 return this->ParseTailCallExpression(classifier, ok); | |
2459 } | |
2460 | |
2366 ExpressionT result = | 2461 ExpressionT result = |
2367 this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK); | 2462 this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK); |
2368 | 2463 |
2369 while (true) { | 2464 while (true) { |
2370 switch (peek()) { | 2465 switch (peek()) { |
2371 case Token::LBRACK: { | 2466 case Token::LBRACK: { |
2467 ValidateTailCallExpression(classifier, CHECK_OK); | |
2372 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2468 Traits::RewriteNonPattern(classifier, CHECK_OK); |
2373 BindingPatternUnexpectedToken(classifier); | 2469 BindingPatternUnexpectedToken(classifier); |
2374 ArrowFormalParametersUnexpectedToken(classifier); | 2470 ArrowFormalParametersUnexpectedToken(classifier); |
2375 Consume(Token::LBRACK); | 2471 Consume(Token::LBRACK); |
2376 int pos = position(); | 2472 int pos = position(); |
2377 ExpressionT index = ParseExpression(true, classifier, CHECK_OK); | 2473 ExpressionT index = ParseExpression(true, classifier, CHECK_OK); |
2378 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2474 Traits::RewriteNonPattern(classifier, CHECK_OK); |
2379 result = factory()->NewProperty(result, index, pos); | 2475 result = factory()->NewProperty(result, index, pos); |
2380 Expect(Token::RBRACK, CHECK_OK); | 2476 Expect(Token::RBRACK, CHECK_OK); |
2381 break; | 2477 break; |
2382 } | 2478 } |
2383 | 2479 |
2384 case Token::LPAREN: { | 2480 case Token::LPAREN: { |
2481 ValidateTailCallExpression(classifier, CHECK_OK); | |
2385 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2482 Traits::RewriteNonPattern(classifier, CHECK_OK); |
2386 BindingPatternUnexpectedToken(classifier); | 2483 BindingPatternUnexpectedToken(classifier); |
2387 ArrowFormalParametersUnexpectedToken(classifier); | 2484 ArrowFormalParametersUnexpectedToken(classifier); |
2388 | 2485 |
2389 int pos; | 2486 int pos; |
2390 if (scanner()->current_token() == Token::IDENTIFIER || | 2487 if (scanner()->current_token() == Token::IDENTIFIER || |
2391 scanner()->current_token() == Token::SUPER) { | 2488 scanner()->current_token() == Token::SUPER) { |
2392 // For call of an identifier we want to report position of | 2489 // For call of an identifier we want to report position of |
2393 // the identifier as position of the call in the stack trace. | 2490 // the identifier as position of the call in the stack trace. |
2394 pos = position(); | 2491 pos = position(); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2433 ExpressionT this_expr = this->ThisExpression(scope_, factory(), pos); | 2530 ExpressionT this_expr = this->ThisExpression(scope_, factory(), pos); |
2434 result = | 2531 result = |
2435 factory()->NewAssignment(Token::INIT, this_expr, result, pos); | 2532 factory()->NewAssignment(Token::INIT, this_expr, result, pos); |
2436 } | 2533 } |
2437 | 2534 |
2438 if (fni_ != NULL) fni_->RemoveLastFunction(); | 2535 if (fni_ != NULL) fni_->RemoveLastFunction(); |
2439 break; | 2536 break; |
2440 } | 2537 } |
2441 | 2538 |
2442 case Token::PERIOD: { | 2539 case Token::PERIOD: { |
2540 ValidateTailCallExpression(classifier, CHECK_OK); | |
2443 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2541 Traits::RewriteNonPattern(classifier, CHECK_OK); |
2444 BindingPatternUnexpectedToken(classifier); | 2542 BindingPatternUnexpectedToken(classifier); |
2445 ArrowFormalParametersUnexpectedToken(classifier); | 2543 ArrowFormalParametersUnexpectedToken(classifier); |
2446 Consume(Token::PERIOD); | 2544 Consume(Token::PERIOD); |
2447 int pos = position(); | 2545 int pos = position(); |
2448 IdentifierT name = ParseIdentifierName(CHECK_OK); | 2546 IdentifierT name = ParseIdentifierName(CHECK_OK); |
2449 result = factory()->NewProperty( | 2547 result = factory()->NewProperty( |
2450 result, factory()->NewStringLiteral(name, pos), pos); | 2548 result, factory()->NewStringLiteral(name, pos), pos); |
2451 if (fni_ != NULL) this->PushLiteralName(fni_, name); | 2549 if (fni_ != NULL) this->PushLiteralName(fni_, name); |
2452 break; | 2550 break; |
2453 } | 2551 } |
2454 | 2552 |
2455 case Token::TEMPLATE_SPAN: | 2553 case Token::TEMPLATE_SPAN: |
2456 case Token::TEMPLATE_TAIL: { | 2554 case Token::TEMPLATE_TAIL: { |
2555 ValidateTailCallExpression(classifier, CHECK_OK); | |
2457 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2556 Traits::RewriteNonPattern(classifier, CHECK_OK); |
2458 BindingPatternUnexpectedToken(classifier); | 2557 BindingPatternUnexpectedToken(classifier); |
2459 ArrowFormalParametersUnexpectedToken(classifier); | 2558 ArrowFormalParametersUnexpectedToken(classifier); |
2460 result = ParseTemplateLiteral(result, position(), classifier, CHECK_OK); | 2559 result = ParseTemplateLiteral(result, position(), classifier, CHECK_OK); |
2461 break; | 2560 break; |
2462 } | 2561 } |
2463 | 2562 |
2464 default: | 2563 default: |
2465 return result; | 2564 return result; |
2466 } | 2565 } |
(...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2924 this->EmptyIdentifier(), RelocInfo::kNoPosition, formal_parameters, | 3023 this->EmptyIdentifier(), RelocInfo::kNoPosition, formal_parameters, |
2925 kArrowFunction, FunctionLiteral::kAnonymousExpression, CHECK_OK); | 3024 kArrowFunction, FunctionLiteral::kAnonymousExpression, CHECK_OK); |
2926 materialized_literal_count = | 3025 materialized_literal_count = |
2927 function_state.materialized_literal_count(); | 3026 function_state.materialized_literal_count(); |
2928 expected_property_count = function_state.expected_property_count(); | 3027 expected_property_count = function_state.expected_property_count(); |
2929 } | 3028 } |
2930 } else { | 3029 } else { |
2931 // Single-expression body | 3030 // Single-expression body |
2932 int pos = position(); | 3031 int pos = position(); |
2933 ExpressionClassifier classifier(this); | 3032 ExpressionClassifier classifier(this); |
2934 bool is_tail_call_expression; | 3033 DCHECK(ReturnExprContext::kInsideValidBlock == |
2935 if (FLAG_harmony_explicit_tailcalls) { | 3034 function_state_->return_expr_context()); |
2936 // TODO(ishell): update chapter number. | 3035 ReturnExprScope allow_tail_calls( |
2937 // ES8 XX.YY.ZZ | 3036 function_state_, ReturnExprContext::kInsideValidReturnStatement); |
2938 if (peek() == Token::CONTINUE) { | |
2939 Consume(Token::CONTINUE); | |
2940 pos = position(); | |
2941 is_tail_call_expression = true; | |
2942 } else { | |
2943 is_tail_call_expression = false; | |
2944 } | |
2945 } else { | |
2946 // ES6 14.6.1 Static Semantics: IsInTailPosition | |
2947 is_tail_call_expression = | |
2948 allow_tailcalls() && !is_sloppy(language_mode()); | |
2949 } | |
2950 ExpressionT expression = | 3037 ExpressionT expression = |
2951 ParseAssignmentExpression(accept_IN, &classifier, CHECK_OK); | 3038 ParseAssignmentExpression(accept_IN, &classifier, CHECK_OK); |
2952 Traits::RewriteNonPattern(&classifier, CHECK_OK); | 3039 Traits::RewriteNonPattern(&classifier, CHECK_OK); |
2953 body = this->NewStatementList(1, zone()); | 3040 body = this->NewStatementList(1, zone()); |
2954 this->AddParameterInitializationBlock(formal_parameters, body, CHECK_OK); | 3041 this->AddParameterInitializationBlock(formal_parameters, body, CHECK_OK); |
2955 body->Add(factory()->NewReturnStatement(expression, pos), zone()); | 3042 body->Add(factory()->NewReturnStatement(expression, pos), zone()); |
2956 materialized_literal_count = function_state.materialized_literal_count(); | 3043 materialized_literal_count = function_state.materialized_literal_count(); |
2957 expected_property_count = function_state.expected_property_count(); | 3044 expected_property_count = function_state.expected_property_count(); |
2958 if (is_tail_call_expression) { | 3045 if (allow_tailcalls() && !is_sloppy(language_mode())) { |
3046 // ES6 14.6.1 Static Semantics: IsInTailPosition | |
2959 this->MarkTailPosition(expression); | 3047 this->MarkTailPosition(expression); |
2960 } | 3048 } |
3049 this->MarkCollectedTailCallExpressions(); | |
2961 } | 3050 } |
2962 super_loc = function_state.super_location(); | 3051 super_loc = function_state.super_location(); |
2963 | 3052 |
2964 formal_parameters.scope->set_end_position(scanner()->location().end_pos); | 3053 formal_parameters.scope->set_end_position(scanner()->location().end_pos); |
2965 | 3054 |
2966 // Arrow function formal parameters are parsed as StrictFormalParameterList, | 3055 // Arrow function formal parameters are parsed as StrictFormalParameterList, |
2967 // which is not the same as "parameters of a strict function"; it only means | 3056 // which is not the same as "parameters of a strict function"; it only means |
2968 // that duplicates are not allowed. Of course, the arrow function may | 3057 // that duplicates are not allowed. Of course, the arrow function may |
2969 // itself be strict as well. | 3058 // itself be strict as well. |
2970 const bool allow_duplicate_parameters = false; | 3059 const bool allow_duplicate_parameters = false; |
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3207 has_seen_constructor_ = true; | 3296 has_seen_constructor_ = true; |
3208 return; | 3297 return; |
3209 } | 3298 } |
3210 } | 3299 } |
3211 | 3300 |
3212 | 3301 |
3213 } // namespace internal | 3302 } // namespace internal |
3214 } // namespace v8 | 3303 } // namespace v8 |
3215 | 3304 |
3216 #endif // V8_PARSING_PARSER_BASE_H | 3305 #endif // V8_PARSING_PARSER_BASE_H |
OLD | NEW |