| 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 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 184 | 184 |
| 185 struct DestructuringAssignment { | 185 struct DestructuringAssignment { |
| 186 public: | 186 public: |
| 187 DestructuringAssignment(ExpressionT expression, Scope* scope) | 187 DestructuringAssignment(ExpressionT expression, Scope* scope) |
| 188 : assignment(expression), scope(scope) {} | 188 : assignment(expression), scope(scope) {} |
| 189 | 189 |
| 190 ExpressionT assignment; | 190 ExpressionT assignment; |
| 191 Scope* scope; | 191 Scope* scope; |
| 192 }; | 192 }; |
| 193 | 193 |
| 194 struct TailCallExpression { | 194 class TailCallExpressionList { |
| 195 TailCallExpression(ExpressionT expression, int pos) | 195 public: |
| 196 : expression(expression), pos(pos) {} | 196 explicit TailCallExpressionList(Zone* zone) |
| 197 : zone_(zone), expressions_(0, zone) {} |
| 197 | 198 |
| 198 ExpressionT expression; | 199 const ZoneList<ExpressionT>& expressions() const { return expressions_; } |
| 199 int pos; | 200 const Scanner::Location& location() const { return loc_; } |
| 201 |
| 202 bool is_empty() const { return expressions_.is_empty(); } |
| 203 |
| 204 void Swap(TailCallExpressionList& other) { |
| 205 expressions_.Swap(&other.expressions_); |
| 206 std::swap(loc_, other.loc_); |
| 207 } |
| 208 |
| 209 void Add(ExpressionT expr, const Scanner::Location& loc) { |
| 210 if (expressions_.is_empty()) loc_ = loc; |
| 211 expressions_.Add(expr, zone_); |
| 212 } |
| 213 |
| 214 void Append(const TailCallExpressionList& other) { |
| 215 if (expressions_.is_empty()) loc_ = other.loc_; |
| 216 expressions_.AddAll(other.expressions_, zone_); |
| 217 } |
| 218 |
| 219 private: |
| 220 Zone* zone_; |
| 221 ZoneList<ExpressionT> expressions_; |
| 222 Scanner::Location loc_; |
| 200 }; | 223 }; |
| 201 | 224 |
| 202 // Defines whether tail call expressions are allowed or not. | 225 // Defines whether tail call expressions are allowed or not. |
| 203 enum class ReturnExprContext { | 226 enum class ReturnExprContext { |
| 204 // Tail call expressions are allowed. | 227 // We are inside return statement which is allowed to contain tail call |
| 205 kNormal, | 228 // expressions. Tail call expressions are allowed. |
| 206 // Tail call expressions are not allowed. | 229 kInsideValidReturnStatement, |
| 230 |
| 231 // We are inside a block in which tail call expressions are allowed but |
| 232 // not yet inside a return statement. |
| 233 kInsideValidBlock, |
| 234 |
| 235 // Tail call expressions are not allowed in the following blocks. |
| 207 kInsideTryBlock, | 236 kInsideTryBlock, |
| 208 kInsideForInOfBody, | 237 kInsideForInOfBody, |
| 209 }; | 238 }; |
| 210 | 239 |
| 211 class FunctionState BASE_EMBEDDED { | 240 class FunctionState BASE_EMBEDDED { |
| 212 public: | 241 public: |
| 213 FunctionState(FunctionState** function_state_stack, Scope** scope_stack, | 242 FunctionState(FunctionState** function_state_stack, Scope** scope_stack, |
| 214 Scope* scope, FunctionKind kind, | 243 Scope* scope, FunctionKind kind, |
| 215 typename Traits::Type::Factory* factory); | 244 typename Traits::Type::Factory* factory); |
| 216 ~FunctionState(); | 245 ~FunctionState(); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 258 return generator_object_variable_; | 287 return generator_object_variable_; |
| 259 } | 288 } |
| 260 | 289 |
| 261 typename Traits::Type::Factory* factory() { return factory_; } | 290 typename Traits::Type::Factory* factory() { return factory_; } |
| 262 | 291 |
| 263 const List<DestructuringAssignment>& destructuring_assignments_to_rewrite() | 292 const List<DestructuringAssignment>& destructuring_assignments_to_rewrite() |
| 264 const { | 293 const { |
| 265 return destructuring_assignments_to_rewrite_; | 294 return destructuring_assignments_to_rewrite_; |
| 266 } | 295 } |
| 267 | 296 |
| 268 List<TailCallExpression>& expressions_in_tail_position() { | 297 TailCallExpressionList& tail_call_expressions() { |
| 269 return expressions_in_tail_position_; | 298 return tail_call_expressions_; |
| 270 } | 299 } |
| 271 void AddExpressionInTailPosition(ExpressionT expression, int pos) { | 300 void AddExpressionInTailPosition(ExpressionT expression, |
| 272 if (return_expr_context() == ReturnExprContext::kNormal) { | 301 const Scanner::Location& loc) { |
| 273 expressions_in_tail_position_.Add(TailCallExpression(expression, pos)); | 302 // If only FLAG_harmony_explicit_tailcalls is enabled then expression |
| 303 // must be a Call expression. |
| 304 DCHECK(FLAG_harmony_tailcalls || !FLAG_harmony_explicit_tailcalls || |
| 305 expression->IsCall()); |
| 306 if (return_expr_context() == |
| 307 ReturnExprContext::kInsideValidReturnStatement) { |
| 308 tail_call_expressions_.Add(expression, loc); |
| 274 } | 309 } |
| 275 } | 310 } |
| 276 | 311 |
| 277 ReturnExprContext return_expr_context() const { | 312 ReturnExprContext return_expr_context() const { |
| 278 return return_expr_context_; | 313 return return_expr_context_; |
| 279 } | 314 } |
| 280 void set_return_expr_context(ReturnExprContext context) { | 315 void set_return_expr_context(ReturnExprContext context) { |
| 281 return_expr_context_ = context; | 316 return_expr_context_ = context; |
| 282 } | 317 } |
| 283 | 318 |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 326 // is used by yield expressions and return statements. It is not necessary | 361 // is used by yield expressions and return statements. It is not necessary |
| 327 // for generator functions to have this variable set. | 362 // for generator functions to have this variable set. |
| 328 Variable* generator_object_variable_; | 363 Variable* generator_object_variable_; |
| 329 | 364 |
| 330 FunctionState** function_state_stack_; | 365 FunctionState** function_state_stack_; |
| 331 FunctionState* outer_function_state_; | 366 FunctionState* outer_function_state_; |
| 332 Scope** scope_stack_; | 367 Scope** scope_stack_; |
| 333 Scope* outer_scope_; | 368 Scope* outer_scope_; |
| 334 | 369 |
| 335 List<DestructuringAssignment> destructuring_assignments_to_rewrite_; | 370 List<DestructuringAssignment> destructuring_assignments_to_rewrite_; |
| 336 List<TailCallExpression> expressions_in_tail_position_; | 371 TailCallExpressionList tail_call_expressions_; |
| 337 ReturnExprContext return_expr_context_; | 372 ReturnExprContext return_expr_context_; |
| 338 ZoneList<ExpressionT> non_patterns_to_rewrite_; | 373 ZoneList<ExpressionT> non_patterns_to_rewrite_; |
| 339 | 374 |
| 340 typename Traits::Type::Factory* factory_; | 375 typename Traits::Type::Factory* factory_; |
| 341 | 376 |
| 342 // If true, the next (and immediately following) function literal is | 377 // If true, the next (and immediately following) function literal is |
| 343 // preceded by a parenthesis. | 378 // preceded by a parenthesis. |
| 344 bool next_function_is_parenthesized_; | 379 bool next_function_is_parenthesized_; |
| 345 | 380 |
| 346 // The value of the parents' next_function_is_parenthesized_, as it applies | 381 // The value of the parents' next_function_is_parenthesized_, as it applies |
| 347 // to this function. Filled in by constructor. | 382 // to this function. Filled in by constructor. |
| 348 bool this_function_is_parenthesized_; | 383 bool this_function_is_parenthesized_; |
| 349 | 384 |
| 350 friend class ParserTraits; | 385 friend class ParserTraits; |
| 351 friend class PreParserTraits; | 386 friend class PreParserTraits; |
| 352 friend class Checkpoint; | 387 friend class Checkpoint; |
| 353 }; | 388 }; |
| 354 | 389 |
| 355 // This scope sets current ReturnExprContext to given value. | 390 // This scope sets current ReturnExprContext to given value. |
| 356 class ReturnExprScope { | 391 class ReturnExprScope { |
| 357 public: | 392 public: |
| 358 explicit ReturnExprScope(FunctionState* function_state, | 393 explicit ReturnExprScope(FunctionState* function_state, |
| 359 ReturnExprContext return_expr_context) | 394 ReturnExprContext return_expr_context) |
| 360 : function_state_(function_state), | 395 : function_state_(function_state), |
| 361 sav_return_expr_context_(function_state->return_expr_context()) { | 396 sav_return_expr_context_(function_state->return_expr_context()) { |
| 362 function_state->set_return_expr_context(return_expr_context); | 397 // Don't update context if we are requested to enable tail call |
| 398 // expressions but current block does not allow them. |
| 399 if (return_expr_context != |
| 400 ReturnExprContext::kInsideValidReturnStatement || |
| 401 sav_return_expr_context_ == ReturnExprContext::kInsideValidBlock) { |
| 402 function_state->set_return_expr_context(return_expr_context); |
| 403 } |
| 363 } | 404 } |
| 364 ~ReturnExprScope() { | 405 ~ReturnExprScope() { |
| 365 function_state_->set_return_expr_context(sav_return_expr_context_); | 406 function_state_->set_return_expr_context(sav_return_expr_context_); |
| 366 } | 407 } |
| 367 | 408 |
| 368 private: | 409 private: |
| 369 FunctionState* function_state_; | 410 FunctionState* function_state_; |
| 370 ReturnExprContext sav_return_expr_context_; | 411 ReturnExprContext sav_return_expr_context_; |
| 371 }; | 412 }; |
| 372 | 413 |
| 373 // Collects all return expressions at tail call position in this scope | 414 // Collects all return expressions at tail call position in this scope |
| 374 // to a separate list. | 415 // to a separate list. |
| 375 class CollectExpressionsInTailPositionToListScope { | 416 class CollectExpressionsInTailPositionToListScope { |
| 376 public: | 417 public: |
| 377 CollectExpressionsInTailPositionToListScope(FunctionState* function_state, | 418 CollectExpressionsInTailPositionToListScope(FunctionState* function_state, |
| 378 List<TailCallExpression>* list) | 419 TailCallExpressionList* list) |
| 379 : function_state_(function_state), list_(list) { | 420 : function_state_(function_state), list_(list) { |
| 380 function_state->expressions_in_tail_position().Swap(list_); | 421 function_state->tail_call_expressions().Swap(*list_); |
| 381 } | 422 } |
| 382 ~CollectExpressionsInTailPositionToListScope() { | 423 ~CollectExpressionsInTailPositionToListScope() { |
| 383 function_state_->expressions_in_tail_position().Swap(list_); | 424 function_state_->tail_call_expressions().Swap(*list_); |
| 384 } | 425 } |
| 385 | 426 |
| 386 private: | 427 private: |
| 387 FunctionState* function_state_; | 428 FunctionState* function_state_; |
| 388 List<TailCallExpression>* list_; | 429 TailCallExpressionList* list_; |
| 389 }; | 430 }; |
| 390 | 431 |
| 391 // Annoyingly, arrow functions first parse as comma expressions, then when we | 432 // Annoyingly, arrow functions first parse as comma expressions, then when we |
| 392 // see the => we have to go back and reinterpret the arguments as being formal | 433 // see the => we have to go back and reinterpret the arguments as being formal |
| 393 // parameters. To do so we need to reset some of the parser state back to | 434 // parameters. To do so we need to reset some of the parser state back to |
| 394 // what it was before the arguments were first seen. | 435 // what it was before the arguments were first seen. |
| 395 class Checkpoint BASE_EMBEDDED { | 436 class Checkpoint BASE_EMBEDDED { |
| 396 public: | 437 public: |
| 397 explicit Checkpoint(ParserBase* parser) { | 438 explicit Checkpoint(ParserBase* parser) { |
| 398 function_state_ = parser->function_state_; | 439 function_state_ = parser->function_state_; |
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 636 Traits::ReportMessageAt(source_location, message, arg, error_type); | 677 Traits::ReportMessageAt(source_location, message, arg, error_type); |
| 637 } | 678 } |
| 638 | 679 |
| 639 void ReportMessageAt(Scanner::Location location, | 680 void ReportMessageAt(Scanner::Location location, |
| 640 MessageTemplate::Template message, | 681 MessageTemplate::Template message, |
| 641 ParseErrorType error_type = kSyntaxError) { | 682 ParseErrorType error_type = kSyntaxError) { |
| 642 Traits::ReportMessageAt(location, message, reinterpret_cast<const char*>(0), | 683 Traits::ReportMessageAt(location, message, reinterpret_cast<const char*>(0), |
| 643 error_type); | 684 error_type); |
| 644 } | 685 } |
| 645 | 686 |
| 646 void ReportIllegalTailCallAt(int pos, ReturnExprContext return_expr_context) { | |
| 647 Scanner::Location loc(pos, pos + 1); | |
| 648 MessageTemplate::Template msg = MessageTemplate::kNone; | |
| 649 switch (return_expr_context) { | |
| 650 case ReturnExprContext::kNormal: | |
| 651 UNREACHABLE(); | |
| 652 return; | |
| 653 case ReturnExprContext::kInsideTryBlock: | |
| 654 msg = MessageTemplate::kTailCallInTryBlock; | |
| 655 break; | |
| 656 case ReturnExprContext::kInsideForInOfBody: | |
| 657 msg = MessageTemplate::kTailCallInForInOf; | |
| 658 break; | |
| 659 } | |
| 660 ReportMessageAt(loc, msg); | |
| 661 } | |
| 662 | |
| 663 void GetUnexpectedTokenMessage( | 687 void GetUnexpectedTokenMessage( |
| 664 Token::Value token, MessageTemplate::Template* message, | 688 Token::Value token, MessageTemplate::Template* message, |
| 665 Scanner::Location* location, const char** arg, | 689 Scanner::Location* location, const char** arg, |
| 666 MessageTemplate::Template default_ = MessageTemplate::kUnexpectedToken); | 690 MessageTemplate::Template default_ = MessageTemplate::kUnexpectedToken); |
| 667 | 691 |
| 668 void ReportUnexpectedToken(Token::Value token); | 692 void ReportUnexpectedToken(Token::Value token); |
| 669 void ReportUnexpectedTokenAt( | 693 void ReportUnexpectedTokenAt( |
| 670 Scanner::Location location, Token::Value token, | 694 Scanner::Location location, Token::Value token, |
| 671 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken); | 695 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken); |
| 672 | 696 |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 753 } | 777 } |
| 754 } | 778 } |
| 755 | 779 |
| 756 void ValidateLetPattern(const ExpressionClassifier* classifier, bool* ok) { | 780 void ValidateLetPattern(const ExpressionClassifier* classifier, bool* ok) { |
| 757 if (!classifier->is_valid_let_pattern()) { | 781 if (!classifier->is_valid_let_pattern()) { |
| 758 ReportClassifierError(classifier->let_pattern_error()); | 782 ReportClassifierError(classifier->let_pattern_error()); |
| 759 *ok = false; | 783 *ok = false; |
| 760 } | 784 } |
| 761 } | 785 } |
| 762 | 786 |
| 787 void CheckNoTailCallExpressions(const ExpressionClassifier* classifier, |
| 788 bool* ok) { |
| 789 if (FLAG_harmony_explicit_tailcalls && |
| 790 classifier->has_tail_call_expression()) { |
| 791 ReportClassifierError(classifier->tail_call_expression_error()); |
| 792 *ok = false; |
| 793 } |
| 794 } |
| 795 |
| 763 void ExpressionUnexpectedToken(ExpressionClassifier* classifier) { | 796 void ExpressionUnexpectedToken(ExpressionClassifier* classifier) { |
| 764 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken; | 797 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken; |
| 765 const char* arg; | 798 const char* arg; |
| 766 Scanner::Location location = scanner()->peek_location(); | 799 Scanner::Location location = scanner()->peek_location(); |
| 767 GetUnexpectedTokenMessage(peek(), &message, &location, &arg); | 800 GetUnexpectedTokenMessage(peek(), &message, &location, &arg); |
| 768 classifier->RecordExpressionError(location, message, arg); | 801 classifier->RecordExpressionError(location, message, arg); |
| 769 } | 802 } |
| 770 | 803 |
| 771 void BindingPatternUnexpectedToken(ExpressionClassifier* classifier) { | 804 void BindingPatternUnexpectedToken(ExpressionClassifier* classifier) { |
| 772 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken; | 805 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken; |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 830 ExpressionClassifier* classifier, IdentifierT* name, bool* ok); | 863 ExpressionClassifier* classifier, IdentifierT* name, bool* ok); |
| 831 typename Traits::Type::ExpressionList ParseArguments( | 864 typename Traits::Type::ExpressionList ParseArguments( |
| 832 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier, | 865 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier, |
| 833 bool* ok); | 866 bool* ok); |
| 834 | 867 |
| 835 ExpressionT ParseAssignmentExpression(bool accept_IN, | 868 ExpressionT ParseAssignmentExpression(bool accept_IN, |
| 836 ExpressionClassifier* classifier, | 869 ExpressionClassifier* classifier, |
| 837 bool* ok); | 870 bool* ok); |
| 838 ExpressionT ParseYieldExpression(bool accept_IN, | 871 ExpressionT ParseYieldExpression(bool accept_IN, |
| 839 ExpressionClassifier* classifier, bool* ok); | 872 ExpressionClassifier* classifier, bool* ok); |
| 873 ExpressionT ParseTailCallExpression(ExpressionClassifier* classifier, |
| 874 bool* ok); |
| 840 ExpressionT ParseConditionalExpression(bool accept_IN, | 875 ExpressionT ParseConditionalExpression(bool accept_IN, |
| 841 ExpressionClassifier* classifier, | 876 ExpressionClassifier* classifier, |
| 842 bool* ok); | 877 bool* ok); |
| 843 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, | 878 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, |
| 844 ExpressionClassifier* classifier, bool* ok); | 879 ExpressionClassifier* classifier, bool* ok); |
| 845 ExpressionT ParseUnaryExpression(ExpressionClassifier* classifier, bool* ok); | 880 ExpressionT ParseUnaryExpression(ExpressionClassifier* classifier, bool* ok); |
| 846 ExpressionT ParsePostfixExpression(ExpressionClassifier* classifier, | 881 ExpressionT ParsePostfixExpression(ExpressionClassifier* classifier, |
| 847 bool* ok); | 882 bool* ok); |
| 848 ExpressionT ParseLeftHandSideExpression(ExpressionClassifier* classifier, | 883 ExpressionT ParseLeftHandSideExpression(ExpressionClassifier* classifier, |
| 849 bool* ok); | 884 bool* ok); |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1006 expected_property_count_(0), | 1041 expected_property_count_(0), |
| 1007 this_location_(Scanner::Location::invalid()), | 1042 this_location_(Scanner::Location::invalid()), |
| 1008 return_location_(Scanner::Location::invalid()), | 1043 return_location_(Scanner::Location::invalid()), |
| 1009 super_location_(Scanner::Location::invalid()), | 1044 super_location_(Scanner::Location::invalid()), |
| 1010 kind_(kind), | 1045 kind_(kind), |
| 1011 generator_object_variable_(NULL), | 1046 generator_object_variable_(NULL), |
| 1012 function_state_stack_(function_state_stack), | 1047 function_state_stack_(function_state_stack), |
| 1013 outer_function_state_(*function_state_stack), | 1048 outer_function_state_(*function_state_stack), |
| 1014 scope_stack_(scope_stack), | 1049 scope_stack_(scope_stack), |
| 1015 outer_scope_(*scope_stack), | 1050 outer_scope_(*scope_stack), |
| 1016 return_expr_context_(ReturnExprContext::kNormal), | 1051 tail_call_expressions_(scope->zone()), |
| 1052 return_expr_context_(ReturnExprContext::kInsideValidBlock), |
| 1017 non_patterns_to_rewrite_(0, scope->zone()), | 1053 non_patterns_to_rewrite_(0, scope->zone()), |
| 1018 factory_(factory), | 1054 factory_(factory), |
| 1019 next_function_is_parenthesized_(false), | 1055 next_function_is_parenthesized_(false), |
| 1020 this_function_is_parenthesized_(false) { | 1056 this_function_is_parenthesized_(false) { |
| 1021 *scope_stack_ = scope; | 1057 *scope_stack_ = scope; |
| 1022 *function_state_stack = this; | 1058 *function_state_stack = this; |
| 1023 if (outer_function_state_) { | 1059 if (outer_function_state_) { |
| 1024 this_function_is_parenthesized_ = | 1060 this_function_is_parenthesized_ = |
| 1025 outer_function_state_->next_function_is_parenthesized_; | 1061 outer_function_state_->next_function_is_parenthesized_; |
| 1026 outer_function_state_->next_function_is_parenthesized_ = false; | 1062 outer_function_state_->next_function_is_parenthesized_ = false; |
| (...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1447 | 1483 |
| 1448 template <class Traits> | 1484 template <class Traits> |
| 1449 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( | 1485 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( |
| 1450 bool accept_IN, bool* ok) { | 1486 bool accept_IN, bool* ok) { |
| 1451 ExpressionClassifier classifier(this); | 1487 ExpressionClassifier classifier(this); |
| 1452 ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK); | 1488 ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK); |
| 1453 Traits::RewriteNonPattern(&classifier, CHECK_OK); | 1489 Traits::RewriteNonPattern(&classifier, CHECK_OK); |
| 1454 return result; | 1490 return result; |
| 1455 } | 1491 } |
| 1456 | 1492 |
| 1457 | |
| 1458 template <class Traits> | 1493 template <class Traits> |
| 1459 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( | 1494 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( |
| 1460 bool accept_IN, ExpressionClassifier* classifier, bool* ok) { | 1495 bool accept_IN, ExpressionClassifier* classifier, bool* ok) { |
| 1461 // Expression :: | 1496 // Expression :: |
| 1462 // AssignmentExpression | 1497 // AssignmentExpression |
| 1463 // Expression ',' AssignmentExpression | 1498 // Expression ',' AssignmentExpression |
| 1464 | 1499 |
| 1465 ExpressionClassifier binding_classifier(this); | 1500 ExpressionClassifier binding_classifier(this); |
| 1466 ExpressionT result = | 1501 ExpressionT result = |
| 1467 this->ParseAssignmentExpression(accept_IN, &binding_classifier, CHECK_OK); | 1502 this->ParseAssignmentExpression(accept_IN, &binding_classifier, CHECK_OK); |
| 1468 classifier->Accumulate(&binding_classifier, | 1503 classifier->Accumulate(&binding_classifier, |
| 1469 ExpressionClassifier::AllProductions); | 1504 ExpressionClassifier::AllProductions); |
| 1470 bool is_simple_parameter_list = this->IsIdentifier(result); | 1505 bool is_simple_parameter_list = this->IsIdentifier(result); |
| 1471 bool seen_rest = false; | 1506 bool seen_rest = false; |
| 1472 while (peek() == Token::COMMA) { | 1507 while (peek() == Token::COMMA) { |
| 1508 CheckNoTailCallExpressions(classifier, CHECK_OK); |
| 1473 if (seen_rest) { | 1509 if (seen_rest) { |
| 1474 // At this point the production can't possibly be valid, but we don't know | 1510 // At this point the production can't possibly be valid, but we don't know |
| 1475 // which error to signal. | 1511 // which error to signal. |
| 1476 classifier->RecordArrowFormalParametersError( | 1512 classifier->RecordArrowFormalParametersError( |
| 1477 scanner()->peek_location(), MessageTemplate::kParamAfterRest); | 1513 scanner()->peek_location(), MessageTemplate::kParamAfterRest); |
| 1478 } | 1514 } |
| 1479 Consume(Token::COMMA); | 1515 Consume(Token::COMMA); |
| 1480 bool is_rest = false; | 1516 bool is_rest = false; |
| 1481 if (peek() == Token::ELLIPSIS) { | 1517 if (peek() == Token::ELLIPSIS) { |
| 1482 // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only | 1518 // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1526 while (peek() != Token::RBRACK) { | 1562 while (peek() != Token::RBRACK) { |
| 1527 ExpressionT elem = this->EmptyExpression(); | 1563 ExpressionT elem = this->EmptyExpression(); |
| 1528 if (peek() == Token::COMMA) { | 1564 if (peek() == Token::COMMA) { |
| 1529 elem = this->GetLiteralTheHole(peek_position(), factory()); | 1565 elem = this->GetLiteralTheHole(peek_position(), factory()); |
| 1530 } else if (peek() == Token::ELLIPSIS) { | 1566 } else if (peek() == Token::ELLIPSIS) { |
| 1531 int start_pos = peek_position(); | 1567 int start_pos = peek_position(); |
| 1532 Consume(Token::ELLIPSIS); | 1568 Consume(Token::ELLIPSIS); |
| 1533 int expr_pos = peek_position(); | 1569 int expr_pos = peek_position(); |
| 1534 ExpressionT argument = | 1570 ExpressionT argument = |
| 1535 this->ParseAssignmentExpression(true, classifier, CHECK_OK); | 1571 this->ParseAssignmentExpression(true, classifier, CHECK_OK); |
| 1572 CheckNoTailCallExpressions(classifier, CHECK_OK); |
| 1536 elem = factory()->NewSpread(argument, start_pos, expr_pos); | 1573 elem = factory()->NewSpread(argument, start_pos, expr_pos); |
| 1537 | 1574 |
| 1538 if (first_spread_index < 0) { | 1575 if (first_spread_index < 0) { |
| 1539 first_spread_index = values->length(); | 1576 first_spread_index = values->length(); |
| 1540 } | 1577 } |
| 1541 | 1578 |
| 1542 if (argument->IsAssignment()) { | 1579 if (argument->IsAssignment()) { |
| 1543 classifier->RecordPatternError( | 1580 classifier->RecordPatternError( |
| 1544 Scanner::Location(start_pos, scanner()->location().end_pos), | 1581 Scanner::Location(start_pos, scanner()->location().end_pos), |
| 1545 MessageTemplate::kInvalidDestructuringTarget); | 1582 MessageTemplate::kInvalidDestructuringTarget); |
| 1546 } else { | 1583 } else { |
| 1547 CheckDestructuringElement(argument, classifier, start_pos, | 1584 CheckDestructuringElement(argument, classifier, start_pos, |
| 1548 scanner()->location().end_pos); | 1585 scanner()->location().end_pos); |
| 1549 } | 1586 } |
| 1550 | 1587 |
| 1551 if (peek() == Token::COMMA) { | 1588 if (peek() == Token::COMMA) { |
| 1552 classifier->RecordPatternError( | 1589 classifier->RecordPatternError( |
| 1553 Scanner::Location(start_pos, scanner()->location().end_pos), | 1590 Scanner::Location(start_pos, scanner()->location().end_pos), |
| 1554 MessageTemplate::kElementAfterRest); | 1591 MessageTemplate::kElementAfterRest); |
| 1555 } | 1592 } |
| 1556 } else { | 1593 } else { |
| 1557 int beg_pos = peek_position(); | 1594 int beg_pos = peek_position(); |
| 1558 elem = this->ParseAssignmentExpression(true, classifier, CHECK_OK); | 1595 elem = this->ParseAssignmentExpression(true, classifier, CHECK_OK); |
| 1596 CheckNoTailCallExpressions(classifier, CHECK_OK); |
| 1559 CheckDestructuringElement(elem, classifier, beg_pos, | 1597 CheckDestructuringElement(elem, classifier, beg_pos, |
| 1560 scanner()->location().end_pos); | 1598 scanner()->location().end_pos); |
| 1561 } | 1599 } |
| 1562 values->Add(elem, zone_); | 1600 values->Add(elem, zone_); |
| 1563 if (peek() != Token::RBRACK) { | 1601 if (peek() != Token::RBRACK) { |
| 1564 Expect(Token::COMMA, CHECK_OK); | 1602 Expect(Token::COMMA, CHECK_OK); |
| 1565 } | 1603 } |
| 1566 } | 1604 } |
| 1567 Expect(Token::RBRACK, CHECK_OK); | 1605 Expect(Token::RBRACK, CHECK_OK); |
| 1568 | 1606 |
| (...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1896 bool done = (peek() == Token::RPAREN); | 1934 bool done = (peek() == Token::RPAREN); |
| 1897 bool was_unspread = false; | 1935 bool was_unspread = false; |
| 1898 int unspread_sequences_count = 0; | 1936 int unspread_sequences_count = 0; |
| 1899 while (!done) { | 1937 while (!done) { |
| 1900 int start_pos = peek_position(); | 1938 int start_pos = peek_position(); |
| 1901 bool is_spread = Check(Token::ELLIPSIS); | 1939 bool is_spread = Check(Token::ELLIPSIS); |
| 1902 int expr_pos = peek_position(); | 1940 int expr_pos = peek_position(); |
| 1903 | 1941 |
| 1904 ExpressionT argument = this->ParseAssignmentExpression( | 1942 ExpressionT argument = this->ParseAssignmentExpression( |
| 1905 true, classifier, CHECK_OK_CUSTOM(NullExpressionList)); | 1943 true, classifier, CHECK_OK_CUSTOM(NullExpressionList)); |
| 1944 CheckNoTailCallExpressions(classifier, CHECK_OK_CUSTOM(NullExpressionList)); |
| 1906 Traits::RewriteNonPattern(classifier, CHECK_OK_CUSTOM(NullExpressionList)); | 1945 Traits::RewriteNonPattern(classifier, CHECK_OK_CUSTOM(NullExpressionList)); |
| 1907 if (is_spread) { | 1946 if (is_spread) { |
| 1908 if (!spread_arg.IsValid()) { | 1947 if (!spread_arg.IsValid()) { |
| 1909 spread_arg.beg_pos = start_pos; | 1948 spread_arg.beg_pos = start_pos; |
| 1910 spread_arg.end_pos = peek_position(); | 1949 spread_arg.end_pos = peek_position(); |
| 1911 } | 1950 } |
| 1912 argument = factory()->NewSpread(argument, start_pos, expr_pos); | 1951 argument = factory()->NewSpread(argument, start_pos, expr_pos); |
| 1913 } | 1952 } |
| 1914 result->Add(argument, zone_); | 1953 result->Add(argument, zone_); |
| 1915 | 1954 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1954 template <class Traits> | 1993 template <class Traits> |
| 1955 typename ParserBase<Traits>::ExpressionT | 1994 typename ParserBase<Traits>::ExpressionT |
| 1956 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, | 1995 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, |
| 1957 ExpressionClassifier* classifier, | 1996 ExpressionClassifier* classifier, |
| 1958 bool* ok) { | 1997 bool* ok) { |
| 1959 // AssignmentExpression :: | 1998 // AssignmentExpression :: |
| 1960 // ConditionalExpression | 1999 // ConditionalExpression |
| 1961 // ArrowFunction | 2000 // ArrowFunction |
| 1962 // YieldExpression | 2001 // YieldExpression |
| 1963 // LeftHandSideExpression AssignmentOperator AssignmentExpression | 2002 // LeftHandSideExpression AssignmentOperator AssignmentExpression |
| 1964 // TailCallExpression | |
| 1965 bool is_destructuring_assignment = false; | 2003 bool is_destructuring_assignment = false; |
| 1966 int lhs_beg_pos = peek_position(); | 2004 int lhs_beg_pos = peek_position(); |
| 1967 | 2005 |
| 1968 if (peek() == Token::YIELD && is_generator()) { | 2006 if (peek() == Token::YIELD && is_generator()) { |
| 1969 return this->ParseYieldExpression(accept_IN, classifier, ok); | 2007 return this->ParseYieldExpression(accept_IN, classifier, ok); |
| 1970 } | 2008 } |
| 1971 | 2009 |
| 1972 FuncNameInferrer::State fni_state(fni_); | 2010 FuncNameInferrer::State fni_state(fni_); |
| 1973 ParserBase<Traits>::Checkpoint checkpoint(this); | 2011 ParserBase<Traits>::Checkpoint checkpoint(this); |
| 1974 ExpressionClassifier arrow_formals_classifier(this, | 2012 ExpressionClassifier arrow_formals_classifier(this, |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2040 if (!Token::IsAssignmentOp(peek())) { | 2078 if (!Token::IsAssignmentOp(peek())) { |
| 2041 // Parsed conditional expression only (no assignment). | 2079 // Parsed conditional expression only (no assignment). |
| 2042 // Now pending non-pattern expressions must be merged. | 2080 // Now pending non-pattern expressions must be merged. |
| 2043 classifier->MergeNonPatterns(&arrow_formals_classifier); | 2081 classifier->MergeNonPatterns(&arrow_formals_classifier); |
| 2044 return expression; | 2082 return expression; |
| 2045 } | 2083 } |
| 2046 | 2084 |
| 2047 // Now pending non-pattern expressions must be discarded. | 2085 // Now pending non-pattern expressions must be discarded. |
| 2048 arrow_formals_classifier.Discard(); | 2086 arrow_formals_classifier.Discard(); |
| 2049 | 2087 |
| 2088 CheckNoTailCallExpressions(classifier, CHECK_OK); |
| 2089 |
| 2050 if (IsValidPattern(expression) && peek() == Token::ASSIGN) { | 2090 if (IsValidPattern(expression) && peek() == Token::ASSIGN) { |
| 2051 classifier->ForgiveCoverInitializedNameError(); | 2091 classifier->ForgiveCoverInitializedNameError(); |
| 2052 ValidateAssignmentPattern(classifier, CHECK_OK); | 2092 ValidateAssignmentPattern(classifier, CHECK_OK); |
| 2053 is_destructuring_assignment = true; | 2093 is_destructuring_assignment = true; |
| 2054 } else { | 2094 } else { |
| 2055 expression = this->CheckAndRewriteReferenceExpression( | 2095 expression = this->CheckAndRewriteReferenceExpression( |
| 2056 expression, lhs_beg_pos, scanner()->location().end_pos, | 2096 expression, lhs_beg_pos, scanner()->location().end_pos, |
| 2057 MessageTemplate::kInvalidLhsInAssignment, CHECK_OK); | 2097 MessageTemplate::kInvalidLhsInAssignment, CHECK_OK); |
| 2058 } | 2098 } |
| 2059 | 2099 |
| 2060 expression = this->MarkExpressionAsAssigned(expression); | 2100 expression = this->MarkExpressionAsAssigned(expression); |
| 2061 | 2101 |
| 2062 Token::Value op = Next(); // Get assignment operator. | 2102 Token::Value op = Next(); // Get assignment operator. |
| 2063 if (op != Token::ASSIGN) { | 2103 if (op != Token::ASSIGN) { |
| 2064 classifier->RecordPatternError(scanner()->location(), | 2104 classifier->RecordPatternError(scanner()->location(), |
| 2065 MessageTemplate::kUnexpectedToken, | 2105 MessageTemplate::kUnexpectedToken, |
| 2066 Token::String(op)); | 2106 Token::String(op)); |
| 2067 } | 2107 } |
| 2068 int pos = position(); | 2108 int pos = position(); |
| 2069 | 2109 |
| 2070 ExpressionClassifier rhs_classifier(this); | 2110 ExpressionClassifier rhs_classifier(this); |
| 2071 | 2111 |
| 2072 ExpressionT right = | 2112 ExpressionT right = |
| 2073 this->ParseAssignmentExpression(accept_IN, &rhs_classifier, CHECK_OK); | 2113 this->ParseAssignmentExpression(accept_IN, &rhs_classifier, CHECK_OK); |
| 2114 CheckNoTailCallExpressions(&rhs_classifier, CHECK_OK); |
| 2074 Traits::RewriteNonPattern(&rhs_classifier, CHECK_OK); | 2115 Traits::RewriteNonPattern(&rhs_classifier, CHECK_OK); |
| 2075 classifier->Accumulate( | 2116 classifier->Accumulate( |
| 2076 &rhs_classifier, ExpressionClassifier::ExpressionProductions | | 2117 &rhs_classifier, ExpressionClassifier::ExpressionProductions | |
| 2077 ExpressionClassifier::CoverInitializedNameProduction); | 2118 ExpressionClassifier::CoverInitializedNameProduction); |
| 2078 | 2119 |
| 2079 // TODO(1231235): We try to estimate the set of properties set by | 2120 // TODO(1231235): We try to estimate the set of properties set by |
| 2080 // constructors. We define a new property whenever there is an | 2121 // constructors. We define a new property whenever there is an |
| 2081 // assignment to a property of 'this'. We should probably only add | 2122 // assignment to a property of 'this'. We should probably only add |
| 2082 // properties if we haven't seen them before. Otherwise we'll | 2123 // properties if we haven't seen them before. Otherwise we'll |
| 2083 // probably overestimate the number of properties. | 2124 // probably overestimate the number of properties. |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2163 } | 2204 } |
| 2164 | 2205 |
| 2165 expression = Traits::BuildIteratorResult(expression, false); | 2206 expression = Traits::BuildIteratorResult(expression, false); |
| 2166 // Hackily disambiguate o from o.next and o [Symbol.iterator](). | 2207 // Hackily disambiguate o from o.next and o [Symbol.iterator](). |
| 2167 // TODO(verwaest): Come up with a better solution. | 2208 // TODO(verwaest): Come up with a better solution. |
| 2168 typename Traits::Type::YieldExpression yield = | 2209 typename Traits::Type::YieldExpression yield = |
| 2169 factory()->NewYield(generator_object, expression, pos); | 2210 factory()->NewYield(generator_object, expression, pos); |
| 2170 return yield; | 2211 return yield; |
| 2171 } | 2212 } |
| 2172 | 2213 |
| 2214 template <class Traits> |
| 2215 typename ParserBase<Traits>::ExpressionT |
| 2216 ParserBase<Traits>::ParseTailCallExpression(ExpressionClassifier* classifier, |
| 2217 bool* ok) { |
| 2218 // TailCallExpression:: |
| 2219 // 'continue' MemberExpression Arguments |
| 2220 // 'continue' CallExpression Arguments |
| 2221 // 'continue' MemberExpression TemplateLiteral |
| 2222 // 'continue' CallExpression TemplateLiteral |
| 2223 Expect(Token::CONTINUE, CHECK_OK); |
| 2224 int pos = position(); |
| 2225 int sub_expression_pos = peek_position(); |
| 2226 ExpressionT expression = |
| 2227 this->ParseLeftHandSideExpression(classifier, CHECK_OK); |
| 2228 CheckNoTailCallExpressions(classifier, CHECK_OK); |
| 2229 |
| 2230 Scanner::Location loc(pos, scanner()->location().end_pos); |
| 2231 ReturnExprContext return_expr_context = |
| 2232 function_state_->return_expr_context(); |
| 2233 if (return_expr_context != ReturnExprContext::kInsideValidReturnStatement) { |
| 2234 MessageTemplate::Template msg = MessageTemplate::kNone; |
| 2235 switch (return_expr_context) { |
| 2236 case ReturnExprContext::kInsideValidReturnStatement: |
| 2237 UNREACHABLE(); |
| 2238 return Traits::EmptyExpression(); |
| 2239 case ReturnExprContext::kInsideValidBlock: |
| 2240 msg = MessageTemplate::kUnexpectedTailCall; |
| 2241 break; |
| 2242 case ReturnExprContext::kInsideTryBlock: |
| 2243 msg = MessageTemplate::kUnexpectedTailCallInTryBlock; |
| 2244 break; |
| 2245 case ReturnExprContext::kInsideForInOfBody: |
| 2246 msg = MessageTemplate::kUnexpectedTailCallInForInOf; |
| 2247 break; |
| 2248 } |
| 2249 ReportMessageAt(loc, msg); |
| 2250 *ok = false; |
| 2251 return Traits::EmptyExpression(); |
| 2252 } |
| 2253 if (!expression->IsCall()) { |
| 2254 Scanner::Location sub_loc(sub_expression_pos, loc.end_pos); |
| 2255 ReportMessageAt(sub_loc, MessageTemplate::kUnexpectedInsideTailCall); |
| 2256 *ok = false; |
| 2257 return Traits::EmptyExpression(); |
| 2258 } |
| 2259 classifier->RecordTailCallExpressionError( |
| 2260 loc, MessageTemplate::kUnexpectedTailCall); |
| 2261 function_state_->AddExpressionInTailPosition(expression, loc); |
| 2262 return expression; |
| 2263 } |
| 2173 | 2264 |
| 2174 // Precedence = 3 | 2265 // Precedence = 3 |
| 2175 template <class Traits> | 2266 template <class Traits> |
| 2176 typename ParserBase<Traits>::ExpressionT | 2267 typename ParserBase<Traits>::ExpressionT |
| 2177 ParserBase<Traits>::ParseConditionalExpression(bool accept_IN, | 2268 ParserBase<Traits>::ParseConditionalExpression(bool accept_IN, |
| 2178 ExpressionClassifier* classifier, | 2269 ExpressionClassifier* classifier, |
| 2179 bool* ok) { | 2270 bool* ok) { |
| 2180 // ConditionalExpression :: | 2271 // ConditionalExpression :: |
| 2181 // LogicalOrExpression | 2272 // LogicalOrExpression |
| 2182 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression | 2273 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression |
| 2183 | 2274 |
| 2184 int pos = peek_position(); | 2275 int pos = peek_position(); |
| 2185 // We start using the binary expression parser for prec >= 4 only! | 2276 // We start using the binary expression parser for prec >= 4 only! |
| 2186 ExpressionT expression = | 2277 ExpressionT expression = |
| 2187 this->ParseBinaryExpression(4, accept_IN, classifier, CHECK_OK); | 2278 this->ParseBinaryExpression(4, accept_IN, classifier, CHECK_OK); |
| 2188 if (peek() != Token::CONDITIONAL) return expression; | 2279 if (peek() != Token::CONDITIONAL) return expression; |
| 2280 CheckNoTailCallExpressions(classifier, CHECK_OK); |
| 2189 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2281 Traits::RewriteNonPattern(classifier, CHECK_OK); |
| 2190 ArrowFormalParametersUnexpectedToken(classifier); | 2282 ArrowFormalParametersUnexpectedToken(classifier); |
| 2191 BindingPatternUnexpectedToken(classifier); | 2283 BindingPatternUnexpectedToken(classifier); |
| 2192 Consume(Token::CONDITIONAL); | 2284 Consume(Token::CONDITIONAL); |
| 2193 // In parsing the first assignment expression in conditional | 2285 // In parsing the first assignment expression in conditional |
| 2194 // expressions we always accept the 'in' keyword; see ECMA-262, | 2286 // expressions we always accept the 'in' keyword; see ECMA-262, |
| 2195 // section 11.12, page 58. | 2287 // section 11.12, page 58. |
| 2196 ExpressionT left = ParseAssignmentExpression(true, classifier, CHECK_OK); | 2288 ExpressionT left = ParseAssignmentExpression(true, classifier, CHECK_OK); |
| 2197 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2289 Traits::RewriteNonPattern(classifier, CHECK_OK); |
| 2198 Expect(Token::COLON, CHECK_OK); | 2290 Expect(Token::COLON, CHECK_OK); |
| 2199 ExpressionT right = | 2291 ExpressionT right = |
| 2200 ParseAssignmentExpression(accept_IN, classifier, CHECK_OK); | 2292 ParseAssignmentExpression(accept_IN, classifier, CHECK_OK); |
| 2201 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2293 Traits::RewriteNonPattern(classifier, CHECK_OK); |
| 2202 return factory()->NewConditional(expression, left, right, pos); | 2294 return factory()->NewConditional(expression, left, right, pos); |
| 2203 } | 2295 } |
| 2204 | 2296 |
| 2205 | 2297 |
| 2206 // Precedence >= 4 | 2298 // Precedence >= 4 |
| 2207 template <class Traits> | 2299 template <class Traits> |
| 2208 typename ParserBase<Traits>::ExpressionT | 2300 typename ParserBase<Traits>::ExpressionT |
| 2209 ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN, | 2301 ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN, |
| 2210 ExpressionClassifier* classifier, | 2302 ExpressionClassifier* classifier, |
| 2211 bool* ok) { | 2303 bool* ok) { |
| 2212 DCHECK(prec >= 4); | 2304 DCHECK(prec >= 4); |
| 2213 ExpressionT x = this->ParseUnaryExpression(classifier, CHECK_OK); | 2305 ExpressionT x = this->ParseUnaryExpression(classifier, CHECK_OK); |
| 2214 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { | 2306 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { |
| 2215 // prec1 >= 4 | 2307 // prec1 >= 4 |
| 2216 while (Precedence(peek(), accept_IN) == prec1) { | 2308 while (Precedence(peek(), accept_IN) == prec1) { |
| 2309 CheckNoTailCallExpressions(classifier, CHECK_OK); |
| 2217 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2310 Traits::RewriteNonPattern(classifier, CHECK_OK); |
| 2218 BindingPatternUnexpectedToken(classifier); | 2311 BindingPatternUnexpectedToken(classifier); |
| 2219 ArrowFormalParametersUnexpectedToken(classifier); | 2312 ArrowFormalParametersUnexpectedToken(classifier); |
| 2220 Token::Value op = Next(); | 2313 Token::Value op = Next(); |
| 2221 int pos = position(); | 2314 int pos = position(); |
| 2222 | 2315 |
| 2223 const bool is_right_associative = op == Token::EXP; | 2316 const bool is_right_associative = op == Token::EXP; |
| 2224 const int next_prec = is_right_associative ? prec1 : prec1 + 1; | 2317 const int next_prec = is_right_associative ? prec1 : prec1 + 1; |
| 2225 ExpressionT y = | 2318 ExpressionT y = |
| 2226 ParseBinaryExpression(next_prec, accept_IN, classifier, CHECK_OK); | 2319 ParseBinaryExpression(next_prec, accept_IN, classifier, CHECK_OK); |
| 2320 if (op != Token::OR && op != Token::AND) { |
| 2321 CheckNoTailCallExpressions(classifier, CHECK_OK); |
| 2322 } |
| 2227 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2323 Traits::RewriteNonPattern(classifier, CHECK_OK); |
| 2228 | 2324 |
| 2229 if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos, | 2325 if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos, |
| 2230 factory())) { | 2326 factory())) { |
| 2231 continue; | 2327 continue; |
| 2232 } | 2328 } |
| 2233 | 2329 |
| 2234 // For now we distinguish between comparisons and other binary | 2330 // For now we distinguish between comparisons and other binary |
| 2235 // operations. (We could combine the two and get rid of this | 2331 // operations. (We could combine the two and get rid of this |
| 2236 // code and AST node eventually.) | 2332 // code and AST node eventually.) |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2281 // '!' UnaryExpression | 2377 // '!' UnaryExpression |
| 2282 | 2378 |
| 2283 Token::Value op = peek(); | 2379 Token::Value op = peek(); |
| 2284 if (Token::IsUnaryOp(op)) { | 2380 if (Token::IsUnaryOp(op)) { |
| 2285 BindingPatternUnexpectedToken(classifier); | 2381 BindingPatternUnexpectedToken(classifier); |
| 2286 ArrowFormalParametersUnexpectedToken(classifier); | 2382 ArrowFormalParametersUnexpectedToken(classifier); |
| 2287 | 2383 |
| 2288 op = Next(); | 2384 op = Next(); |
| 2289 int pos = position(); | 2385 int pos = position(); |
| 2290 ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK); | 2386 ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK); |
| 2387 CheckNoTailCallExpressions(classifier, CHECK_OK); |
| 2291 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2388 Traits::RewriteNonPattern(classifier, CHECK_OK); |
| 2292 | 2389 |
| 2293 if (op == Token::DELETE && is_strict(language_mode())) { | 2390 if (op == Token::DELETE && is_strict(language_mode())) { |
| 2294 if (this->IsIdentifier(expression)) { | 2391 if (this->IsIdentifier(expression)) { |
| 2295 // "delete identifier" is a syntax error in strict mode. | 2392 // "delete identifier" is a syntax error in strict mode. |
| 2296 ReportMessage(MessageTemplate::kStrictDelete); | 2393 ReportMessage(MessageTemplate::kStrictDelete); |
| 2297 *ok = false; | 2394 *ok = false; |
| 2298 return this->EmptyExpression(); | 2395 return this->EmptyExpression(); |
| 2299 } | 2396 } |
| 2300 } | 2397 } |
| 2301 | 2398 |
| 2302 if (peek() == Token::EXP) { | 2399 if (peek() == Token::EXP) { |
| 2303 ReportUnexpectedToken(Next()); | 2400 ReportUnexpectedToken(Next()); |
| 2304 *ok = false; | 2401 *ok = false; |
| 2305 return this->EmptyExpression(); | 2402 return this->EmptyExpression(); |
| 2306 } | 2403 } |
| 2307 | 2404 |
| 2308 // Allow Traits do rewrite the expression. | 2405 // Allow Traits do rewrite the expression. |
| 2309 return this->BuildUnaryExpression(expression, op, pos, factory()); | 2406 return this->BuildUnaryExpression(expression, op, pos, factory()); |
| 2310 } else if (Token::IsCountOp(op)) { | 2407 } else if (Token::IsCountOp(op)) { |
| 2311 BindingPatternUnexpectedToken(classifier); | 2408 BindingPatternUnexpectedToken(classifier); |
| 2312 ArrowFormalParametersUnexpectedToken(classifier); | 2409 ArrowFormalParametersUnexpectedToken(classifier); |
| 2313 op = Next(); | 2410 op = Next(); |
| 2314 int beg_pos = peek_position(); | 2411 int beg_pos = peek_position(); |
| 2315 ExpressionT expression = this->ParseUnaryExpression(classifier, CHECK_OK); | 2412 ExpressionT expression = this->ParseUnaryExpression(classifier, CHECK_OK); |
| 2413 CheckNoTailCallExpressions(classifier, CHECK_OK); |
| 2316 expression = this->CheckAndRewriteReferenceExpression( | 2414 expression = this->CheckAndRewriteReferenceExpression( |
| 2317 expression, beg_pos, scanner()->location().end_pos, | 2415 expression, beg_pos, scanner()->location().end_pos, |
| 2318 MessageTemplate::kInvalidLhsInPrefixOp, CHECK_OK); | 2416 MessageTemplate::kInvalidLhsInPrefixOp, CHECK_OK); |
| 2319 this->MarkExpressionAsAssigned(expression); | 2417 this->MarkExpressionAsAssigned(expression); |
| 2320 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2418 Traits::RewriteNonPattern(classifier, CHECK_OK); |
| 2321 | 2419 |
| 2322 return factory()->NewCountOperation(op, | 2420 return factory()->NewCountOperation(op, |
| 2323 true /* prefix */, | 2421 true /* prefix */, |
| 2324 expression, | 2422 expression, |
| 2325 position()); | 2423 position()); |
| 2326 | 2424 |
| 2327 } else { | 2425 } else { |
| 2328 return this->ParsePostfixExpression(classifier, ok); | 2426 return this->ParsePostfixExpression(classifier, ok); |
| 2329 } | 2427 } |
| 2330 } | 2428 } |
| 2331 | 2429 |
| 2332 | 2430 |
| 2333 template <class Traits> | 2431 template <class Traits> |
| 2334 typename ParserBase<Traits>::ExpressionT | 2432 typename ParserBase<Traits>::ExpressionT |
| 2335 ParserBase<Traits>::ParsePostfixExpression(ExpressionClassifier* classifier, | 2433 ParserBase<Traits>::ParsePostfixExpression(ExpressionClassifier* classifier, |
| 2336 bool* ok) { | 2434 bool* ok) { |
| 2337 // PostfixExpression :: | 2435 // PostfixExpression :: |
| 2338 // LeftHandSideExpression ('++' | '--')? | 2436 // LeftHandSideExpression ('++' | '--')? |
| 2339 | 2437 |
| 2340 int lhs_beg_pos = peek_position(); | 2438 int lhs_beg_pos = peek_position(); |
| 2341 ExpressionT expression = | 2439 ExpressionT expression = |
| 2342 this->ParseLeftHandSideExpression(classifier, CHECK_OK); | 2440 this->ParseLeftHandSideExpression(classifier, CHECK_OK); |
| 2343 if (!scanner()->HasAnyLineTerminatorBeforeNext() && | 2441 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
| 2344 Token::IsCountOp(peek())) { | 2442 Token::IsCountOp(peek())) { |
| 2443 CheckNoTailCallExpressions(classifier, CHECK_OK); |
| 2345 BindingPatternUnexpectedToken(classifier); | 2444 BindingPatternUnexpectedToken(classifier); |
| 2346 ArrowFormalParametersUnexpectedToken(classifier); | 2445 ArrowFormalParametersUnexpectedToken(classifier); |
| 2347 | 2446 |
| 2348 expression = this->CheckAndRewriteReferenceExpression( | 2447 expression = this->CheckAndRewriteReferenceExpression( |
| 2349 expression, lhs_beg_pos, scanner()->location().end_pos, | 2448 expression, lhs_beg_pos, scanner()->location().end_pos, |
| 2350 MessageTemplate::kInvalidLhsInPostfixOp, CHECK_OK); | 2449 MessageTemplate::kInvalidLhsInPostfixOp, CHECK_OK); |
| 2351 expression = this->MarkExpressionAsAssigned(expression); | 2450 expression = this->MarkExpressionAsAssigned(expression); |
| 2352 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2451 Traits::RewriteNonPattern(classifier, CHECK_OK); |
| 2353 | 2452 |
| 2354 Token::Value next = Next(); | 2453 Token::Value next = Next(); |
| 2355 expression = | 2454 expression = |
| 2356 factory()->NewCountOperation(next, | 2455 factory()->NewCountOperation(next, |
| 2357 false /* postfix */, | 2456 false /* postfix */, |
| 2358 expression, | 2457 expression, |
| 2359 position()); | 2458 position()); |
| 2360 } | 2459 } |
| 2361 return expression; | 2460 return expression; |
| 2362 } | 2461 } |
| 2363 | 2462 |
| 2364 | |
| 2365 template <class Traits> | 2463 template <class Traits> |
| 2366 typename ParserBase<Traits>::ExpressionT | 2464 typename ParserBase<Traits>::ExpressionT |
| 2367 ParserBase<Traits>::ParseLeftHandSideExpression( | 2465 ParserBase<Traits>::ParseLeftHandSideExpression( |
| 2368 ExpressionClassifier* classifier, bool* ok) { | 2466 ExpressionClassifier* classifier, bool* ok) { |
| 2369 // LeftHandSideExpression :: | 2467 // LeftHandSideExpression :: |
| 2370 // (NewExpression | MemberExpression) ... | 2468 // (NewExpression | MemberExpression) ... |
| 2371 | 2469 |
| 2470 if (FLAG_harmony_explicit_tailcalls && peek() == Token::CONTINUE) { |
| 2471 return this->ParseTailCallExpression(classifier, ok); |
| 2472 } |
| 2473 |
| 2372 ExpressionT result = | 2474 ExpressionT result = |
| 2373 this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK); | 2475 this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK); |
| 2374 | 2476 |
| 2375 while (true) { | 2477 while (true) { |
| 2376 switch (peek()) { | 2478 switch (peek()) { |
| 2377 case Token::LBRACK: { | 2479 case Token::LBRACK: { |
| 2480 CheckNoTailCallExpressions(classifier, CHECK_OK); |
| 2378 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2481 Traits::RewriteNonPattern(classifier, CHECK_OK); |
| 2379 BindingPatternUnexpectedToken(classifier); | 2482 BindingPatternUnexpectedToken(classifier); |
| 2380 ArrowFormalParametersUnexpectedToken(classifier); | 2483 ArrowFormalParametersUnexpectedToken(classifier); |
| 2381 Consume(Token::LBRACK); | 2484 Consume(Token::LBRACK); |
| 2382 int pos = position(); | 2485 int pos = position(); |
| 2383 ExpressionT index = ParseExpression(true, classifier, CHECK_OK); | 2486 ExpressionT index = ParseExpression(true, classifier, CHECK_OK); |
| 2384 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2487 Traits::RewriteNonPattern(classifier, CHECK_OK); |
| 2385 result = factory()->NewProperty(result, index, pos); | 2488 result = factory()->NewProperty(result, index, pos); |
| 2386 Expect(Token::RBRACK, CHECK_OK); | 2489 Expect(Token::RBRACK, CHECK_OK); |
| 2387 break; | 2490 break; |
| 2388 } | 2491 } |
| 2389 | 2492 |
| 2390 case Token::LPAREN: { | 2493 case Token::LPAREN: { |
| 2494 CheckNoTailCallExpressions(classifier, CHECK_OK); |
| 2391 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2495 Traits::RewriteNonPattern(classifier, CHECK_OK); |
| 2392 BindingPatternUnexpectedToken(classifier); | 2496 BindingPatternUnexpectedToken(classifier); |
| 2393 ArrowFormalParametersUnexpectedToken(classifier); | 2497 ArrowFormalParametersUnexpectedToken(classifier); |
| 2394 | 2498 |
| 2395 int pos; | 2499 int pos; |
| 2396 if (scanner()->current_token() == Token::IDENTIFIER || | 2500 if (scanner()->current_token() == Token::IDENTIFIER || |
| 2397 scanner()->current_token() == Token::SUPER) { | 2501 scanner()->current_token() == Token::SUPER) { |
| 2398 // For call of an identifier we want to report position of | 2502 // For call of an identifier we want to report position of |
| 2399 // the identifier as position of the call in the stack trace. | 2503 // the identifier as position of the call in the stack trace. |
| 2400 pos = position(); | 2504 pos = position(); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2439 ExpressionT this_expr = this->ThisExpression(scope_, factory(), pos); | 2543 ExpressionT this_expr = this->ThisExpression(scope_, factory(), pos); |
| 2440 result = | 2544 result = |
| 2441 factory()->NewAssignment(Token::INIT, this_expr, result, pos); | 2545 factory()->NewAssignment(Token::INIT, this_expr, result, pos); |
| 2442 } | 2546 } |
| 2443 | 2547 |
| 2444 if (fni_ != NULL) fni_->RemoveLastFunction(); | 2548 if (fni_ != NULL) fni_->RemoveLastFunction(); |
| 2445 break; | 2549 break; |
| 2446 } | 2550 } |
| 2447 | 2551 |
| 2448 case Token::PERIOD: { | 2552 case Token::PERIOD: { |
| 2553 CheckNoTailCallExpressions(classifier, CHECK_OK); |
| 2449 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2554 Traits::RewriteNonPattern(classifier, CHECK_OK); |
| 2450 BindingPatternUnexpectedToken(classifier); | 2555 BindingPatternUnexpectedToken(classifier); |
| 2451 ArrowFormalParametersUnexpectedToken(classifier); | 2556 ArrowFormalParametersUnexpectedToken(classifier); |
| 2452 Consume(Token::PERIOD); | 2557 Consume(Token::PERIOD); |
| 2453 int pos = position(); | 2558 int pos = position(); |
| 2454 IdentifierT name = ParseIdentifierName(CHECK_OK); | 2559 IdentifierT name = ParseIdentifierName(CHECK_OK); |
| 2455 result = factory()->NewProperty( | 2560 result = factory()->NewProperty( |
| 2456 result, factory()->NewStringLiteral(name, pos), pos); | 2561 result, factory()->NewStringLiteral(name, pos), pos); |
| 2457 if (fni_ != NULL) this->PushLiteralName(fni_, name); | 2562 if (fni_ != NULL) this->PushLiteralName(fni_, name); |
| 2458 break; | 2563 break; |
| 2459 } | 2564 } |
| 2460 | 2565 |
| 2461 case Token::TEMPLATE_SPAN: | 2566 case Token::TEMPLATE_SPAN: |
| 2462 case Token::TEMPLATE_TAIL: { | 2567 case Token::TEMPLATE_TAIL: { |
| 2568 CheckNoTailCallExpressions(classifier, CHECK_OK); |
| 2463 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2569 Traits::RewriteNonPattern(classifier, CHECK_OK); |
| 2464 BindingPatternUnexpectedToken(classifier); | 2570 BindingPatternUnexpectedToken(classifier); |
| 2465 ArrowFormalParametersUnexpectedToken(classifier); | 2571 ArrowFormalParametersUnexpectedToken(classifier); |
| 2466 result = ParseTemplateLiteral(result, position(), classifier, CHECK_OK); | 2572 result = ParseTemplateLiteral(result, position(), classifier, CHECK_OK); |
| 2467 break; | 2573 break; |
| 2468 } | 2574 } |
| 2469 | 2575 |
| 2470 default: | 2576 default: |
| 2471 return result; | 2577 return result; |
| 2472 } | 2578 } |
| (...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2931 this->EmptyIdentifier(), RelocInfo::kNoPosition, formal_parameters, | 3037 this->EmptyIdentifier(), RelocInfo::kNoPosition, formal_parameters, |
| 2932 kArrowFunction, FunctionLiteral::kAnonymousExpression, CHECK_OK); | 3038 kArrowFunction, FunctionLiteral::kAnonymousExpression, CHECK_OK); |
| 2933 materialized_literal_count = | 3039 materialized_literal_count = |
| 2934 function_state.materialized_literal_count(); | 3040 function_state.materialized_literal_count(); |
| 2935 expected_property_count = function_state.expected_property_count(); | 3041 expected_property_count = function_state.expected_property_count(); |
| 2936 } | 3042 } |
| 2937 } else { | 3043 } else { |
| 2938 // Single-expression body | 3044 // Single-expression body |
| 2939 int pos = position(); | 3045 int pos = position(); |
| 2940 ExpressionClassifier classifier(this); | 3046 ExpressionClassifier classifier(this); |
| 2941 bool is_tail_call_expression; | 3047 DCHECK(ReturnExprContext::kInsideValidBlock == |
| 2942 if (FLAG_harmony_explicit_tailcalls) { | 3048 function_state_->return_expr_context()); |
| 2943 // TODO(ishell): update chapter number. | 3049 ReturnExprScope allow_tail_calls( |
| 2944 // ES8 XX.YY.ZZ | 3050 function_state_, ReturnExprContext::kInsideValidReturnStatement); |
| 2945 if (peek() == Token::CONTINUE) { | |
| 2946 Consume(Token::CONTINUE); | |
| 2947 pos = position(); | |
| 2948 is_tail_call_expression = true; | |
| 2949 } else { | |
| 2950 is_tail_call_expression = false; | |
| 2951 } | |
| 2952 } else { | |
| 2953 // ES6 14.6.1 Static Semantics: IsInTailPosition | |
| 2954 is_tail_call_expression = | |
| 2955 allow_tailcalls() && !is_sloppy(language_mode()); | |
| 2956 } | |
| 2957 ExpressionT expression = | 3051 ExpressionT expression = |
| 2958 ParseAssignmentExpression(accept_IN, &classifier, CHECK_OK); | 3052 ParseAssignmentExpression(accept_IN, &classifier, CHECK_OK); |
| 2959 Traits::RewriteNonPattern(&classifier, CHECK_OK); | 3053 Traits::RewriteNonPattern(&classifier, CHECK_OK); |
| 2960 body = this->NewStatementList(1, zone()); | 3054 body = this->NewStatementList(1, zone()); |
| 2961 this->AddParameterInitializationBlock(formal_parameters, body, CHECK_OK); | 3055 this->AddParameterInitializationBlock(formal_parameters, body, CHECK_OK); |
| 2962 body->Add(factory()->NewReturnStatement(expression, pos), zone()); | 3056 body->Add(factory()->NewReturnStatement(expression, pos), zone()); |
| 2963 materialized_literal_count = function_state.materialized_literal_count(); | 3057 materialized_literal_count = function_state.materialized_literal_count(); |
| 2964 expected_property_count = function_state.expected_property_count(); | 3058 expected_property_count = function_state.expected_property_count(); |
| 2965 if (is_tail_call_expression) { | 3059 if (allow_tailcalls() && !is_sloppy(language_mode())) { |
| 3060 // ES6 14.6.1 Static Semantics: IsInTailPosition |
| 2966 this->MarkTailPosition(expression); | 3061 this->MarkTailPosition(expression); |
| 2967 } | 3062 } |
| 3063 this->MarkCollectedTailCallExpressions(); |
| 2968 } | 3064 } |
| 2969 super_loc = function_state.super_location(); | 3065 super_loc = function_state.super_location(); |
| 2970 | 3066 |
| 2971 formal_parameters.scope->set_end_position(scanner()->location().end_pos); | 3067 formal_parameters.scope->set_end_position(scanner()->location().end_pos); |
| 2972 | 3068 |
| 2973 // Arrow function formal parameters are parsed as StrictFormalParameterList, | 3069 // Arrow function formal parameters are parsed as StrictFormalParameterList, |
| 2974 // which is not the same as "parameters of a strict function"; it only means | 3070 // which is not the same as "parameters of a strict function"; it only means |
| 2975 // that duplicates are not allowed. Of course, the arrow function may | 3071 // that duplicates are not allowed. Of course, the arrow function may |
| 2976 // itself be strict as well. | 3072 // itself be strict as well. |
| 2977 const bool allow_duplicate_parameters = false; | 3073 const bool allow_duplicate_parameters = false; |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3056 } else if (next == Token::ILLEGAL) { | 3152 } else if (next == Token::ILLEGAL) { |
| 3057 Traits::ReportMessageAt( | 3153 Traits::ReportMessageAt( |
| 3058 Scanner::Location(position() + 1, peek_position()), | 3154 Scanner::Location(position() + 1, peek_position()), |
| 3059 MessageTemplate::kUnexpectedToken, "ILLEGAL", kSyntaxError); | 3155 MessageTemplate::kUnexpectedToken, "ILLEGAL", kSyntaxError); |
| 3060 *ok = false; | 3156 *ok = false; |
| 3061 return Traits::EmptyExpression(); | 3157 return Traits::EmptyExpression(); |
| 3062 } | 3158 } |
| 3063 | 3159 |
| 3064 int expr_pos = peek_position(); | 3160 int expr_pos = peek_position(); |
| 3065 ExpressionT expression = this->ParseExpression(true, classifier, CHECK_OK); | 3161 ExpressionT expression = this->ParseExpression(true, classifier, CHECK_OK); |
| 3162 CheckNoTailCallExpressions(classifier, CHECK_OK); |
| 3066 Traits::RewriteNonPattern(classifier, CHECK_OK); | 3163 Traits::RewriteNonPattern(classifier, CHECK_OK); |
| 3067 Traits::AddTemplateExpression(&ts, expression); | 3164 Traits::AddTemplateExpression(&ts, expression); |
| 3068 | 3165 |
| 3069 if (peek() != Token::RBRACE) { | 3166 if (peek() != Token::RBRACE) { |
| 3070 ReportMessageAt(Scanner::Location(expr_pos, peek_position()), | 3167 ReportMessageAt(Scanner::Location(expr_pos, peek_position()), |
| 3071 MessageTemplate::kUnterminatedTemplateExpr); | 3168 MessageTemplate::kUnterminatedTemplateExpr); |
| 3072 *ok = false; | 3169 *ok = false; |
| 3073 return Traits::EmptyExpression(); | 3170 return Traits::EmptyExpression(); |
| 3074 } | 3171 } |
| 3075 | 3172 |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3214 has_seen_constructor_ = true; | 3311 has_seen_constructor_ = true; |
| 3215 return; | 3312 return; |
| 3216 } | 3313 } |
| 3217 } | 3314 } |
| 3218 | 3315 |
| 3219 | 3316 |
| 3220 } // namespace internal | 3317 } // namespace internal |
| 3221 } // namespace v8 | 3318 } // namespace v8 |
| 3222 | 3319 |
| 3223 #endif // V8_PARSING_PARSER_BASE_H | 3320 #endif // V8_PARSING_PARSER_BASE_H |
| OLD | NEW |