Chromium Code Reviews| 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 |