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

Side by Side Diff: src/preparser.h

Issue 1163323006: Speed up ExpressionClassifier::Accumulate (Closed) Base URL: https://chromium.googlesource.com/v8/v8@master
Patch Set: Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef V8_PREPARSER_H 5 #ifndef V8_PREPARSER_H
6 #define V8_PREPARSER_H 6 #define V8_PREPARSER_H
7 7
8 #include "src/v8.h" 8 #include "src/v8.h"
9 9
10 #include "src/bailout-reason.h" 10 #include "src/bailout-reason.h"
(...skipping 539 matching lines...) Expand 10 before | Expand all | Expand 10 after
550 public: 550 public:
551 struct Error { 551 struct Error {
552 Error() 552 Error()
553 : location(Scanner::Location::invalid()), 553 : location(Scanner::Location::invalid()),
554 message(MessageTemplate::kNone), 554 message(MessageTemplate::kNone),
555 arg(nullptr) {} 555 arg(nullptr) {}
556 556
557 Scanner::Location location; 557 Scanner::Location location;
558 MessageTemplate::Template message; 558 MessageTemplate::Template message;
559 const char* arg; 559 const char* arg;
560
561 bool HasError() const { return location.IsValid(); }
562 }; 560 };
563 561
564 ExpressionClassifier() {} 562 enum TargetProduction {
563 ExpressionProduction = 1 << 0,
564 BindingPatternProduction = 1 << 1,
565 AssignmentPatternProduction = 1 << 2,
566 DistinctFormalParametersProduction = 1 << 3,
567 StrictModeFormalParametersProduction = 1 << 4,
568 StrongModeFormalParametersProduction = 1 << 5,
569 ArrowFormalParametersProduction = 1 << 6,
565 570
566 bool is_valid_expression() const { return !expression_error_.HasError(); } 571 PatternProductions =
572 (BindingPatternProduction | AssignmentPatternProduction),
573 FormalParametersProductions = (DistinctFormalParametersProduction |
574 StrictModeFormalParametersProduction |
575 StrongModeFormalParametersProduction),
576 StandardProductions = ExpressionProduction | PatternProductions,
577 AllProductions = (StandardProductions | FormalParametersProductions |
578 ArrowFormalParametersProduction)
579 };
580
581 ExpressionClassifier() : invalid_productions_(0) {}
582
583 bool is_valid(unsigned productions) const {
584 return (invalid_productions_ & productions) == 0;
585 }
586
587 bool is_valid_expression() const { return is_valid(ExpressionProduction); }
567 588
568 bool is_valid_binding_pattern() const { 589 bool is_valid_binding_pattern() const {
569 return !binding_pattern_error_.HasError(); 590 return is_valid(BindingPatternProduction);
570 } 591 }
571 592
572 bool is_valid_assignment_pattern() const { 593 bool is_valid_assignment_pattern() const {
573 return !assignment_pattern_error_.HasError(); 594 return is_valid(AssignmentPatternProduction);
574 } 595 }
575 596
576 bool is_valid_arrow_formal_parameters() const { 597 bool is_valid_arrow_formal_parameters() const {
577 return !arrow_formal_parameters_error_.HasError(); 598 return is_valid(ArrowFormalParametersProduction);
578 } 599 }
579 600
580 bool is_valid_formal_parameter_list_without_duplicates() const { 601 bool is_valid_formal_parameter_list_without_duplicates() const {
581 return !duplicate_formal_parameter_error_.HasError(); 602 return is_valid(DistinctFormalParametersProduction);
582 } 603 }
583 604
584 // Note: callers should also check 605 // Note: callers should also check
585 // is_valid_formal_parameter_list_without_duplicates(). 606 // is_valid_formal_parameter_list_without_duplicates().
586 bool is_valid_strict_mode_formal_parameters() const { 607 bool is_valid_strict_mode_formal_parameters() const {
587 return !strict_mode_formal_parameter_error_.HasError(); 608 return is_valid(StrictModeFormalParametersProduction);
588 } 609 }
589 610
590 // Note: callers should also check is_valid_strict_mode_formal_parameters() 611 // Note: callers should also check is_valid_strict_mode_formal_parameters()
591 // and is_valid_formal_parameter_list_without_duplicates(). 612 // and is_valid_formal_parameter_list_without_duplicates().
592 bool is_valid_strong_mode_formal_parameters() const { 613 bool is_valid_strong_mode_formal_parameters() const {
593 return !strong_mode_formal_parameter_error_.HasError(); 614 return is_valid(StrongModeFormalParametersProduction);
594 } 615 }
595 616
596 const Error& expression_error() const { return expression_error_; } 617 const Error& expression_error() const { return expression_error_; }
597 618
598 const Error& binding_pattern_error() const { 619 const Error& binding_pattern_error() const {
599 return binding_pattern_error_; 620 return binding_pattern_error_;
600 } 621 }
601 622
602 const Error& assignment_pattern_error() const { 623 const Error& assignment_pattern_error() const {
603 return assignment_pattern_error_; 624 return assignment_pattern_error_;
(...skipping 12 matching lines...) Expand all
616 } 637 }
617 638
618 const Error& strong_mode_formal_parameter_error() const { 639 const Error& strong_mode_formal_parameter_error() const {
619 return strong_mode_formal_parameter_error_; 640 return strong_mode_formal_parameter_error_;
620 } 641 }
621 642
622 void RecordExpressionError(const Scanner::Location& loc, 643 void RecordExpressionError(const Scanner::Location& loc,
623 MessageTemplate::Template message, 644 MessageTemplate::Template message,
624 const char* arg = nullptr) { 645 const char* arg = nullptr) {
625 if (!is_valid_expression()) return; 646 if (!is_valid_expression()) return;
647 invalid_productions_ |= ExpressionProduction;
626 expression_error_.location = loc; 648 expression_error_.location = loc;
627 expression_error_.message = message; 649 expression_error_.message = message;
628 expression_error_.arg = arg; 650 expression_error_.arg = arg;
629 } 651 }
630 652
631 void RecordBindingPatternError(const Scanner::Location& loc, 653 void RecordBindingPatternError(const Scanner::Location& loc,
632 MessageTemplate::Template message, 654 MessageTemplate::Template message,
633 const char* arg = nullptr) { 655 const char* arg = nullptr) {
634 if (!is_valid_binding_pattern()) return; 656 if (!is_valid_binding_pattern()) return;
657 invalid_productions_ |= BindingPatternProduction;
635 binding_pattern_error_.location = loc; 658 binding_pattern_error_.location = loc;
636 binding_pattern_error_.message = message; 659 binding_pattern_error_.message = message;
637 binding_pattern_error_.arg = arg; 660 binding_pattern_error_.arg = arg;
638 } 661 }
639 662
640 void RecordAssignmentPatternError(const Scanner::Location& loc, 663 void RecordAssignmentPatternError(const Scanner::Location& loc,
641 MessageTemplate::Template message, 664 MessageTemplate::Template message,
642 const char* arg = nullptr) { 665 const char* arg = nullptr) {
643 if (!is_valid_assignment_pattern()) return; 666 if (!is_valid_assignment_pattern()) return;
667 invalid_productions_ |= AssignmentPatternProduction;
644 assignment_pattern_error_.location = loc; 668 assignment_pattern_error_.location = loc;
645 assignment_pattern_error_.message = message; 669 assignment_pattern_error_.message = message;
646 assignment_pattern_error_.arg = arg; 670 assignment_pattern_error_.arg = arg;
647 } 671 }
648 672
649 void RecordArrowFormalParametersError(const Scanner::Location& loc, 673 void RecordArrowFormalParametersError(const Scanner::Location& loc,
650 MessageTemplate::Template message, 674 MessageTemplate::Template message,
651 const char* arg = nullptr) { 675 const char* arg = nullptr) {
652 if (!is_valid_arrow_formal_parameters()) return; 676 if (!is_valid_arrow_formal_parameters()) return;
677 invalid_productions_ |= ArrowFormalParametersProduction;
653 arrow_formal_parameters_error_.location = loc; 678 arrow_formal_parameters_error_.location = loc;
654 arrow_formal_parameters_error_.message = message; 679 arrow_formal_parameters_error_.message = message;
655 arrow_formal_parameters_error_.arg = arg; 680 arrow_formal_parameters_error_.arg = arg;
656 } 681 }
657 682
658 void RecordDuplicateFormalParameterError(const Scanner::Location& loc) { 683 void RecordDuplicateFormalParameterError(const Scanner::Location& loc) {
659 if (!is_valid_formal_parameter_list_without_duplicates()) return; 684 if (!is_valid_formal_parameter_list_without_duplicates()) return;
685 invalid_productions_ |= DistinctFormalParametersProduction;
660 duplicate_formal_parameter_error_.location = loc; 686 duplicate_formal_parameter_error_.location = loc;
661 duplicate_formal_parameter_error_.message = 687 duplicate_formal_parameter_error_.message =
662 MessageTemplate::kStrictParamDupe; 688 MessageTemplate::kStrictParamDupe;
663 duplicate_formal_parameter_error_.arg = nullptr; 689 duplicate_formal_parameter_error_.arg = nullptr;
664 } 690 }
665 691
666 // Record a binding that would be invalid in strict mode. Confusingly this 692 // Record a binding that would be invalid in strict mode. Confusingly this
667 // is not the same as StrictFormalParameterList, which simply forbids 693 // is not the same as StrictFormalParameterList, which simply forbids
668 // duplicate bindings. 694 // duplicate bindings.
669 void RecordStrictModeFormalParameterError(const Scanner::Location& loc, 695 void RecordStrictModeFormalParameterError(const Scanner::Location& loc,
670 MessageTemplate::Template message, 696 MessageTemplate::Template message,
671 const char* arg = nullptr) { 697 const char* arg = nullptr) {
672 if (!is_valid_strict_mode_formal_parameters()) return; 698 if (!is_valid_strict_mode_formal_parameters()) return;
699 invalid_productions_ |= StrictModeFormalParametersProduction;
673 strict_mode_formal_parameter_error_.location = loc; 700 strict_mode_formal_parameter_error_.location = loc;
674 strict_mode_formal_parameter_error_.message = message; 701 strict_mode_formal_parameter_error_.message = message;
675 strict_mode_formal_parameter_error_.arg = arg; 702 strict_mode_formal_parameter_error_.arg = arg;
676 } 703 }
677 704
678 void RecordStrongModeFormalParameterError(const Scanner::Location& loc, 705 void RecordStrongModeFormalParameterError(const Scanner::Location& loc,
679 MessageTemplate::Template message, 706 MessageTemplate::Template message,
680 const char* arg = nullptr) { 707 const char* arg = nullptr) {
681 if (!is_valid_strong_mode_formal_parameters()) return; 708 if (!is_valid_strong_mode_formal_parameters()) return;
709 invalid_productions_ |= StrongModeFormalParametersProduction;
682 strong_mode_formal_parameter_error_.location = loc; 710 strong_mode_formal_parameter_error_.location = loc;
683 strong_mode_formal_parameter_error_.message = message; 711 strong_mode_formal_parameter_error_.message = message;
684 strong_mode_formal_parameter_error_.arg = arg; 712 strong_mode_formal_parameter_error_.arg = arg;
685 } 713 }
686 714
687 enum TargetProduction {
688 ExpressionProduction = 1 << 0,
689 BindingPatternProduction = 1 << 1,
690 AssignmentPatternProduction = 1 << 2,
691 FormalParametersProduction = 1 << 3,
692 ArrowFormalParametersProduction = 1 << 4,
693 StandardProductions = (ExpressionProduction | BindingPatternProduction |
694 AssignmentPatternProduction),
695 PatternProductions =
696 BindingPatternProduction | AssignmentPatternProduction,
697 AllProductions = (StandardProductions | FormalParametersProduction |
698 ArrowFormalParametersProduction),
699 };
700
701 void Accumulate(const ExpressionClassifier& inner, 715 void Accumulate(const ExpressionClassifier& inner,
702 unsigned productions = StandardProductions) { 716 unsigned productions = StandardProductions) {
703 if (productions & ExpressionProduction && is_valid_expression()) { 717 // Propagate errors from inner, but don't overwrite already recorded
704 expression_error_ = inner.expression_error_; 718 // errors.
705 } 719 unsigned non_arrow_inner_invalid_productions =
706 if (productions & BindingPatternProduction && 720 inner.invalid_productions_ & ~ArrowFormalParametersProduction;
707 is_valid_binding_pattern()) { 721 if (non_arrow_inner_invalid_productions == 0) return;
708 binding_pattern_error_ = inner.binding_pattern_error_; 722 unsigned non_arrow_productions =
709 } 723 productions & ~ArrowFormalParametersProduction;
710 if (productions & AssignmentPatternProduction && 724 unsigned errors =
711 is_valid_assignment_pattern()) { 725 non_arrow_productions & non_arrow_inner_invalid_productions;
712 assignment_pattern_error_ = inner.assignment_pattern_error_; 726 errors &= ~invalid_productions_;
713 } 727 if (errors != 0) {
714 if (productions & FormalParametersProduction) { 728 invalid_productions_ |= errors;
715 if (is_valid_formal_parameter_list_without_duplicates()) { 729 if (errors & ExpressionProduction)
730 expression_error_ = inner.expression_error_;
731 if (errors & BindingPatternProduction)
732 binding_pattern_error_ = inner.binding_pattern_error_;
733 if (errors & AssignmentPatternProduction)
734 assignment_pattern_error_ = inner.assignment_pattern_error_;
735 if (errors & DistinctFormalParametersProduction)
716 duplicate_formal_parameter_error_ = 736 duplicate_formal_parameter_error_ =
717 inner.duplicate_formal_parameter_error_; 737 inner.duplicate_formal_parameter_error_;
718 } 738 if (errors & StrictModeFormalParametersProduction)
719 if (is_valid_strict_mode_formal_parameters()) {
720 strict_mode_formal_parameter_error_ = 739 strict_mode_formal_parameter_error_ =
721 inner.strict_mode_formal_parameter_error_; 740 inner.strict_mode_formal_parameter_error_;
722 } 741 if (errors & StrongModeFormalParametersProduction)
723 if (is_valid_strong_mode_formal_parameters()) {
724 strong_mode_formal_parameter_error_ = 742 strong_mode_formal_parameter_error_ =
725 inner.strong_mode_formal_parameter_error_; 743 inner.strong_mode_formal_parameter_error_;
726 }
727 } 744 }
745
746 // As an exception to the above, the result continues to be a valid arrow
747 // formal parameters if the inner expression is a valid binding pattern.
728 if (productions & ArrowFormalParametersProduction && 748 if (productions & ArrowFormalParametersProduction &&
729 is_valid_arrow_formal_parameters()) { 749 is_valid_arrow_formal_parameters() &&
730 // The result continues to be a valid arrow formal parameters if the 750 !inner.is_valid_binding_pattern()) {
731 // inner expression is a valid binding pattern. 751 invalid_productions_ |= ArrowFormalParametersProduction;
732 arrow_formal_parameters_error_ = inner.binding_pattern_error_; 752 arrow_formal_parameters_error_ = inner.binding_pattern_error_;
733 } 753 }
734 } 754 }
735 755
736 void AccumulateReclassifyingAsPattern(const ExpressionClassifier& inner) { 756 void AccumulateReclassifyingAsPattern(const ExpressionClassifier& inner) {
737 Accumulate(inner, AllProductions & ~PatternProductions); 757 Accumulate(inner, AllProductions & ~PatternProductions);
738 if (!inner.is_valid_expression()) { 758 if (!inner.is_valid_expression()) {
739 if (is_valid_binding_pattern()) { 759 if (is_valid_binding_pattern()) {
740 binding_pattern_error_ = inner.expression_error(); 760 binding_pattern_error_ = inner.expression_error();
741 } 761 }
742 if (is_valid_assignment_pattern()) { 762 if (is_valid_assignment_pattern()) {
743 assignment_pattern_error_ = inner.expression_error(); 763 assignment_pattern_error_ = inner.expression_error();
744 } 764 }
745 } 765 }
746 } 766 }
747 767
748 private: 768 private:
769 unsigned invalid_productions_;
749 Error expression_error_; 770 Error expression_error_;
750 Error binding_pattern_error_; 771 Error binding_pattern_error_;
751 Error assignment_pattern_error_; 772 Error assignment_pattern_error_;
752 Error arrow_formal_parameters_error_; 773 Error arrow_formal_parameters_error_;
753 Error duplicate_formal_parameter_error_; 774 Error duplicate_formal_parameter_error_;
754 Error strict_mode_formal_parameter_error_; 775 Error strict_mode_formal_parameter_error_;
755 Error strong_mode_formal_parameter_error_; 776 Error strong_mode_formal_parameter_error_;
756 }; 777 };
757 778
758 void ReportClassifierError( 779 void ReportClassifierError(
(...skipping 2179 matching lines...) Expand 10 before | Expand all | Expand 10 after
2938 duplicate_loc); 2959 duplicate_loc);
2939 } 2960 }
2940 expression = this->ParseArrowFunctionLiteral( 2961 expression = this->ParseArrowFunctionLiteral(
2941 scope, has_rest, arrow_formals_classifier, CHECK_OK); 2962 scope, has_rest, arrow_formals_classifier, CHECK_OK);
2942 return expression; 2963 return expression;
2943 } 2964 }
2944 2965
2945 // "expression" was not itself an arrow function parameter list, but it might 2966 // "expression" was not itself an arrow function parameter list, but it might
2946 // form part of one. Propagate speculative formal parameter error locations. 2967 // form part of one. Propagate speculative formal parameter error locations.
2947 classifier->Accumulate(arrow_formals_classifier, 2968 classifier->Accumulate(arrow_formals_classifier,
2948 ExpressionClassifier::FormalParametersProduction); 2969 ExpressionClassifier::FormalParametersProductions);
2949 2970
2950 if (!Token::IsAssignmentOp(peek())) { 2971 if (!Token::IsAssignmentOp(peek())) {
2951 if (fni_ != NULL) fni_->Leave(); 2972 if (fni_ != NULL) fni_->Leave();
2952 // Parsed conditional expression only (no assignment). 2973 // Parsed conditional expression only (no assignment).
2953 return expression; 2974 return expression;
2954 } 2975 }
2955 2976
2956 if (!allow_harmony_destructuring()) { 2977 if (!allow_harmony_destructuring()) {
2957 BindingPatternUnexpectedToken(classifier); 2978 BindingPatternUnexpectedToken(classifier);
2958 } 2979 }
(...skipping 1074 matching lines...) Expand 10 before | Expand all | Expand 10 after
4033 *ok = false; 4054 *ok = false;
4034 return; 4055 return;
4035 } 4056 }
4036 has_seen_constructor_ = true; 4057 has_seen_constructor_ = true;
4037 return; 4058 return;
4038 } 4059 }
4039 } 4060 }
4040 } } // v8::internal 4061 } } // v8::internal
4041 4062
4042 #endif // V8_PREPARSER_H 4063 #endif // V8_PREPARSER_H
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698