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

Side by Side Diff: src/jsregexp.h

Issue 12900: Irregexp:... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 12 years 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after
339 // The successors are a list of sets that contain the same values 339 // The successors are a list of sets that contain the same values
340 // as this set and the one more value that is not present in this 340 // as this set and the one more value that is not present in this
341 // set. 341 // set.
342 ZoneList<OutSet*>* successors() { return successors_; } 342 ZoneList<OutSet*>* successors() { return successors_; }
343 343
344 OutSet(uint32_t first, ZoneList<unsigned>* remaining) 344 OutSet(uint32_t first, ZoneList<unsigned>* remaining)
345 : first_(first), remaining_(remaining), successors_(NULL) { } 345 : first_(first), remaining_(remaining), successors_(NULL) { }
346 uint32_t first_; 346 uint32_t first_;
347 ZoneList<unsigned>* remaining_; 347 ZoneList<unsigned>* remaining_;
348 ZoneList<OutSet*>* successors_; 348 ZoneList<OutSet*>* successors_;
349 friend class GenerationVariant;
349 }; 350 };
350 351
351 352
352 // A mapping from integers, specified as ranges, to a set of integers. 353 // A mapping from integers, specified as ranges, to a set of integers.
353 // Used for mapping character ranges to choices. 354 // Used for mapping character ranges to choices.
354 class DispatchTable : public ZoneObject { 355 class DispatchTable : public ZoneObject {
355 public: 356 public:
356 class Entry { 357 class Entry {
357 public: 358 public:
358 Entry() : from_(0), to_(0), out_set_(NULL) { } 359 Entry() : from_(0), to_(0), out_set_(NULL) { }
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
425 426
426 #define FORWARD_DECLARE(Name) class RegExp##Name; 427 #define FORWARD_DECLARE(Name) class RegExp##Name;
427 FOR_EACH_REG_EXP_TREE_TYPE(FORWARD_DECLARE) 428 FOR_EACH_REG_EXP_TREE_TYPE(FORWARD_DECLARE)
428 #undef FORWARD_DECLARE 429 #undef FORWARD_DECLARE
429 430
430 431
431 class TextElement { 432 class TextElement {
432 public: 433 public:
433 enum Type {UNINITIALIZED, ATOM, CHAR_CLASS}; 434 enum Type {UNINITIALIZED, ATOM, CHAR_CLASS};
434 TextElement() : type(UNINITIALIZED) { } 435 TextElement() : type(UNINITIALIZED) { }
435 explicit TextElement(Type t) : type(t) { } 436 explicit TextElement(Type t) : type(t), cp_offset(-1) { }
436 static TextElement Atom(RegExpAtom* atom); 437 static TextElement Atom(RegExpAtom* atom);
437 static TextElement CharClass(RegExpCharacterClass* char_class); 438 static TextElement CharClass(RegExpCharacterClass* char_class);
438 Type type; 439 Type type;
439 union { 440 union {
440 RegExpAtom* u_atom; 441 RegExpAtom* u_atom;
441 RegExpCharacterClass* u_char_class; 442 RegExpCharacterClass* u_char_class;
442 } data; 443 } data;
444 int cp_offset;
443 }; 445 };
444 446
445 447
448 class GenerationVariant;
449
450
446 struct NodeInfo { 451 struct NodeInfo {
447 enum TriBool { 452 enum TriBool {
448 UNKNOWN = -1, FALSE = 0, TRUE = 1 453 UNKNOWN = -1, FALSE = 0, TRUE = 1
449 }; 454 };
450 455
451 NodeInfo() 456 NodeInfo()
452 : being_analyzed(false), 457 : being_analyzed(false),
453 been_analyzed(false), 458 been_analyzed(false),
454 being_expanded(false), 459 being_expanded(false),
455 been_expanded(false), 460 been_expanded(false),
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
600 } 605 }
601 void Add(RegExpNode* node) { list_->Add(node); } 606 void Add(RegExpNode* node) { list_->Add(node); }
602 RegExpNode* Get(int index) { return list_->at(index); } 607 RegExpNode* Get(int index) { return list_->at(index); }
603 private: 608 private:
604 ZoneList<RegExpNode*>* list_; 609 ZoneList<RegExpNode*>* list_;
605 }; 610 };
606 611
607 612
608 class RegExpNode: public ZoneObject { 613 class RegExpNode: public ZoneObject {
609 public: 614 public:
615 RegExpNode() : variants_generated_(0) { }
610 virtual ~RegExpNode() { } 616 virtual ~RegExpNode() { }
611 virtual void Accept(NodeVisitor* visitor) = 0; 617 virtual void Accept(NodeVisitor* visitor) = 0;
612 // Generates a goto to this node or actually generates the code at this point. 618 // Generates a goto to this node or actually generates the code at this point.
613 // Until the implementation is complete we will return true for success and 619 // Until the implementation is complete we will return true for success and
614 // false for failure. 620 // false for failure.
615 virtual bool GoTo(RegExpCompiler* compiler); 621 virtual bool Emit(RegExpCompiler* compiler, GenerationVariant* variant) = 0;
616 Label* label(); 622 static const int kNodeIsTooComplexForGreedyLoops = -1;
617 623 virtual int GreedyLoopTextLength() { return kNodeIsTooComplexForGreedyLoops; }
618 // Until the implementation is complete we will return true for success and 624 Label* label() { return &label_; }
619 // false for failure. 625 static const int kMaxVariantsGenerated = 10;
620 virtual bool Emit(RegExpCompiler* compiler) = 0;
621 626
622 RegExpNode* EnsureExpanded(NodeInfo* info); 627 RegExpNode* EnsureExpanded(NodeInfo* info);
623 virtual RegExpNode* ExpandLocal(NodeInfo* info) = 0; 628 virtual RegExpNode* ExpandLocal(NodeInfo* info) = 0;
624 virtual void ExpandChildren() = 0; 629 virtual void ExpandChildren() = 0;
625 630
626 // Propagates the given interest information forward. When seeing 631 // Propagates the given interest information forward. When seeing
627 // \bfoo for instance, the \b is implemented by propagating forward 632 // \bfoo for instance, the \b is implemented by propagating forward
628 // to the 'foo' string that it should only succeed if its first 633 // to the 'foo' string that it should only succeed if its first
629 // character is a letter xor the previous character was a letter. 634 // character is a letter xor the previous character was a letter.
630 virtual RegExpNode* PropagateForward(NodeInfo* info) = 0; 635 virtual RegExpNode* PropagateForward(NodeInfo* info) = 0;
631 636
632 NodeInfo* info() { return &info_; } 637 NodeInfo* info() { return &info_; }
633 virtual bool IsBacktrack() { return false; }
634 638
635 void AddSibling(RegExpNode* node) { siblings_.Add(node); } 639 void AddSibling(RegExpNode* node) { siblings_.Add(node); }
636 640
637 // Static version of EnsureSibling that expresses the fact that the 641 // Static version of EnsureSibling that expresses the fact that the
638 // result has the same type as the input. 642 // result has the same type as the input.
639 template <class C> 643 template <class C>
640 static C* EnsureSibling(C* node, NodeInfo* info, bool* cloned) { 644 static C* EnsureSibling(C* node, NodeInfo* info, bool* cloned) {
641 return static_cast<C*>(node->EnsureSibling(info, cloned)); 645 return static_cast<C*>(node->EnsureSibling(info, cloned));
642 } 646 }
643 647
644 SiblingList* siblings() { return &siblings_; } 648 SiblingList* siblings() { return &siblings_; }
645 void set_siblings(SiblingList* other) { siblings_ = *other; } 649 void set_siblings(SiblingList* other) { siblings_ = *other; }
646 650
647 protected: 651 protected:
652 enum LimitResult { DONE, FAIL, CONTINUE };
653 LimitResult LimitVersions(RegExpCompiler* compiler,
654 GenerationVariant* variant);
648 655
649 // Returns a sibling of this node whose interests and assumptions 656 // Returns a sibling of this node whose interests and assumptions
650 // match the ones in the given node info. If no sibling exists NULL 657 // match the ones in the given node info. If no sibling exists NULL
651 // is returned. 658 // is returned.
652 RegExpNode* TryGetSibling(NodeInfo* info); 659 RegExpNode* TryGetSibling(NodeInfo* info);
653 660
654 // Returns a sibling of this node whose interests match the ones in 661 // Returns a sibling of this node whose interests match the ones in
655 // the given node info. The info must not contain any assertions. 662 // the given node info. The info must not contain any assertions.
656 // If no node exists a new one will be created by cloning the current 663 // If no node exists a new one will be created by cloning the current
657 // node. The result will always be an instance of the same concrete 664 // node. The result will always be an instance of the same concrete
658 // class as this node. 665 // class as this node.
659 RegExpNode* EnsureSibling(NodeInfo* info, bool* cloned); 666 RegExpNode* EnsureSibling(NodeInfo* info, bool* cloned);
660 667
661 // Returns a clone of this node initialized using the copy constructor 668 // Returns a clone of this node initialized using the copy constructor
662 // of its concrete class. Note that the node may have to be pre- 669 // of its concrete class. Note that the node may have to be pre-
663 // processed before it is on a useable state. 670 // processed before it is on a useable state.
664 virtual RegExpNode* Clone() = 0; 671 virtual RegExpNode* Clone() = 0;
665 672
666 inline void Bind(RegExpMacroAssembler* macro);
667
668 private: 673 private:
669 Label label_; 674 Label label_;
670 NodeInfo info_; 675 NodeInfo info_;
671 SiblingList siblings_; 676 SiblingList siblings_;
677 int variants_generated_;
672 }; 678 };
673 679
674 680
675 class SeqRegExpNode: public RegExpNode { 681 class SeqRegExpNode: public RegExpNode {
676 public: 682 public:
677 explicit SeqRegExpNode(RegExpNode* on_success) 683 explicit SeqRegExpNode(RegExpNode* on_success)
678 : on_success_(on_success) { } 684 : on_success_(on_success) { }
679 RegExpNode* on_success() { return on_success_; } 685 RegExpNode* on_success() { return on_success_; }
680 void set_on_success(RegExpNode* node) { on_success_ = node; } 686 void set_on_success(RegExpNode* node) { on_success_ = node; }
681 virtual bool Emit(RegExpCompiler* compiler) { return false; }
682 private: 687 private:
683 RegExpNode* on_success_; 688 RegExpNode* on_success_;
684 }; 689 };
685 690
686 691
687 class ActionNode: public SeqRegExpNode { 692 class ActionNode: public SeqRegExpNode {
688 public: 693 public:
689 enum Type { 694 enum Type {
690 STORE_REGISTER, 695 SET_REGISTER,
691 INCREMENT_REGISTER, 696 INCREMENT_REGISTER,
692 STORE_POSITION, 697 STORE_POSITION,
693 RESTORE_POSITION,
694 BEGIN_SUBMATCH, 698 BEGIN_SUBMATCH,
695 ESCAPE_SUBMATCH 699 POSITIVE_SUBMATCH_SUCCESS
696 }; 700 };
697 static ActionNode* StoreRegister(int reg, int val, RegExpNode* on_success); 701 static ActionNode* SetRegister(int reg, int val, RegExpNode* on_success);
698 static ActionNode* IncrementRegister(int reg, RegExpNode* on_success); 702 static ActionNode* IncrementRegister(int reg, RegExpNode* on_success);
699 static ActionNode* StorePosition(int reg, RegExpNode* on_success); 703 static ActionNode* StorePosition(int reg, RegExpNode* on_success);
700 static ActionNode* RestorePosition(int reg, RegExpNode* on_success); 704 static ActionNode* BeginSubmatch(
701 static ActionNode* BeginSubmatch(int stack_pointer_reg, 705 int stack_pointer_reg,
702 int position_reg, 706 int position_reg,
703 RegExpNode* on_success); 707 RegExpNode* on_success);
704 static ActionNode* EscapeSubmatch(int stack_pointer_reg, 708 static ActionNode* PositiveSubmatchSuccess(
705 bool and_restore_position, 709 int stack_pointer_reg,
706 int restore_reg, 710 int restore_reg,
707 RegExpNode* on_success); 711 RegExpNode* on_success);
708 virtual void Accept(NodeVisitor* visitor); 712 virtual void Accept(NodeVisitor* visitor);
709 virtual bool Emit(RegExpCompiler* compiler); 713 virtual bool Emit(RegExpCompiler* compiler, GenerationVariant* variant);
710 virtual RegExpNode* ExpandLocal(NodeInfo* info); 714 virtual RegExpNode* ExpandLocal(NodeInfo* info);
711 virtual void ExpandChildren(); 715 virtual void ExpandChildren();
712 virtual RegExpNode* PropagateForward(NodeInfo* info); 716 virtual RegExpNode* PropagateForward(NodeInfo* info);
717 Type type() { return type_; }
718 // TODO(erikcorry): We should allow some action nodes in greedy loops.
719 virtual int GreedyLoopTextLength() { return kNodeIsTooComplexForGreedyLoops; }
713 virtual ActionNode* Clone() { return new ActionNode(*this); } 720 virtual ActionNode* Clone() { return new ActionNode(*this); }
714 721
715 private: 722 private:
716 union { 723 union {
717 struct { 724 struct {
718 int reg; 725 int reg;
719 int value; 726 int value;
720 } u_store_register; 727 } u_store_register;
721 struct { 728 struct {
722 int reg; 729 int reg;
(...skipping 10 matching lines...) Expand all
733 : SeqRegExpNode(on_success), 740 : SeqRegExpNode(on_success),
734 type_(type) { } 741 type_(type) { }
735 Type type_; 742 Type type_;
736 friend class DotPrinter; 743 friend class DotPrinter;
737 }; 744 };
738 745
739 746
740 class TextNode: public SeqRegExpNode { 747 class TextNode: public SeqRegExpNode {
741 public: 748 public:
742 TextNode(ZoneList<TextElement>* elms, 749 TextNode(ZoneList<TextElement>* elms,
743 RegExpNode* on_success, 750 RegExpNode* on_success)
744 RegExpNode* on_failure)
745 : SeqRegExpNode(on_success), 751 : SeqRegExpNode(on_success),
746 on_failure_(on_failure),
747 elms_(elms) { } 752 elms_(elms) { }
748 TextNode(RegExpCharacterClass* that, 753 TextNode(RegExpCharacterClass* that,
749 RegExpNode* on_success, 754 RegExpNode* on_success)
750 RegExpNode* on_failure)
751 : SeqRegExpNode(on_success), 755 : SeqRegExpNode(on_success),
752 on_failure_(on_failure),
753 elms_(new ZoneList<TextElement>(1)) { 756 elms_(new ZoneList<TextElement>(1)) {
754 elms_->Add(TextElement::CharClass(that)); 757 elms_->Add(TextElement::CharClass(that));
755 } 758 }
756 virtual void Accept(NodeVisitor* visitor); 759 virtual void Accept(NodeVisitor* visitor);
757 virtual RegExpNode* PropagateForward(NodeInfo* info); 760 virtual RegExpNode* PropagateForward(NodeInfo* info);
758 virtual RegExpNode* ExpandLocal(NodeInfo* info); 761 virtual RegExpNode* ExpandLocal(NodeInfo* info);
759 virtual void ExpandChildren(); 762 virtual void ExpandChildren();
760 RegExpNode* on_failure() { return on_failure_; } 763 virtual bool Emit(RegExpCompiler* compiler, GenerationVariant* variant);
761 virtual bool Emit(RegExpCompiler* compiler);
762 ZoneList<TextElement>* elements() { return elms_; } 764 ZoneList<TextElement>* elements() { return elms_; }
763 void MakeCaseIndependent(); 765 void MakeCaseIndependent();
764 virtual TextNode* Clone() { return new TextNode(*this); } 766 virtual int GreedyLoopTextLength();
765 767 virtual TextNode* Clone() {
768 TextNode* result = new TextNode(*this);
769 result->CalculateOffsets();
770 return result;
771 }
772 void CalculateOffsets();
766 private: 773 private:
767 void ExpandAtomChildren(RegExpAtom* that); 774 void ExpandAtomChildren(RegExpAtom* that);
768 void ExpandCharClassChildren(RegExpCharacterClass* that); 775 void ExpandCharClassChildren(RegExpCharacterClass* that);
769 776
770 RegExpNode* on_failure_;
771 ZoneList<TextElement>* elms_; 777 ZoneList<TextElement>* elms_;
772 }; 778 };
773 779
774 780
775 class BackReferenceNode: public SeqRegExpNode { 781 class BackReferenceNode: public SeqRegExpNode {
776 public: 782 public:
777 BackReferenceNode(int start_reg, 783 BackReferenceNode(int start_reg,
778 int end_reg, 784 int end_reg,
779 RegExpNode* on_success, 785 RegExpNode* on_success)
780 RegExpNode* on_failure)
781 : SeqRegExpNode(on_success), 786 : SeqRegExpNode(on_success),
782 on_failure_(on_failure),
783 start_reg_(start_reg), 787 start_reg_(start_reg),
784 end_reg_(end_reg) { } 788 end_reg_(end_reg) { }
785 virtual void Accept(NodeVisitor* visitor); 789 virtual void Accept(NodeVisitor* visitor);
786 RegExpNode* on_failure() { return on_failure_; }
787 int start_register() { return start_reg_; } 790 int start_register() { return start_reg_; }
788 int end_register() { return end_reg_; } 791 int end_register() { return end_reg_; }
789 virtual bool Emit(RegExpCompiler* compiler); 792 virtual bool Emit(RegExpCompiler* compiler, GenerationVariant* variant);
790 virtual RegExpNode* PropagateForward(NodeInfo* info); 793 virtual RegExpNode* PropagateForward(NodeInfo* info);
791 virtual RegExpNode* ExpandLocal(NodeInfo* info); 794 virtual RegExpNode* ExpandLocal(NodeInfo* info);
792 virtual void ExpandChildren(); 795 virtual void ExpandChildren();
793 virtual BackReferenceNode* Clone() { return new BackReferenceNode(*this); } 796 virtual BackReferenceNode* Clone() { return new BackReferenceNode(*this); }
794 797
795 private: 798 private:
796 RegExpNode* on_failure_;
797 int start_reg_; 799 int start_reg_;
798 int end_reg_; 800 int end_reg_;
799 }; 801 };
800 802
801 803
802 class EndNode: public RegExpNode { 804 class EndNode: public RegExpNode {
803 public: 805 public:
804 enum Action { ACCEPT, BACKTRACK }; 806 enum Action { ACCEPT, BACKTRACK, NEGATIVE_SUBMATCH_SUCCESS };
805 explicit EndNode(Action action) : action_(action) { } 807 explicit EndNode(Action action) : action_(action) { }
806 virtual void Accept(NodeVisitor* visitor); 808 virtual void Accept(NodeVisitor* visitor);
807 virtual bool Emit(RegExpCompiler* compiler); 809 virtual bool Emit(RegExpCompiler* compiler, GenerationVariant* variant);
808 virtual RegExpNode* PropagateForward(NodeInfo* info); 810 virtual RegExpNode* PropagateForward(NodeInfo* info);
809 virtual RegExpNode* ExpandLocal(NodeInfo* info); 811 virtual RegExpNode* ExpandLocal(NodeInfo* info);
810 virtual void ExpandChildren(); 812 virtual void ExpandChildren();
811 virtual bool IsBacktrack() { return action_ == BACKTRACK; }
812 virtual bool GoTo(RegExpCompiler* compiler);
813 virtual EndNode* Clone() { return new EndNode(*this); } 813 virtual EndNode* Clone() { return new EndNode(*this); }
814 814
815 protected:
816 void EmitInfoChecks(RegExpMacroAssembler* macro, GenerationVariant* variant);
817
815 private: 818 private:
816 Action action_; 819 Action action_;
817 }; 820 };
818 821
819 822
823 class NegativeSubmatchSuccess: public EndNode {
824 public:
825 NegativeSubmatchSuccess(int stack_pointer_reg, int position_reg)
826 : EndNode(NEGATIVE_SUBMATCH_SUCCESS),
827 stack_pointer_register_(stack_pointer_reg),
828 current_position_register_(position_reg) { }
829 virtual bool Emit(RegExpCompiler* compiler, GenerationVariant* variant);
830
831 private:
832 int stack_pointer_register_;
833 int current_position_register_;
834 };
835
836
820 class Guard: public ZoneObject { 837 class Guard: public ZoneObject {
821 public: 838 public:
822 enum Relation { LT, GEQ }; 839 enum Relation { LT, GEQ };
823 Guard(int reg, Relation op, int value) 840 Guard(int reg, Relation op, int value)
824 : reg_(reg), 841 : reg_(reg),
825 op_(op), 842 op_(op),
826 value_(value) { } 843 value_(value) { }
827 int reg() { return reg_; } 844 int reg() { return reg_; }
828 Relation op() { return op_; } 845 Relation op() { return op_; }
829 int value() { return value_; } 846 int value() { return value_; }
(...skipping 14 matching lines...) Expand all
844 ZoneList<Guard*>* guards() { return guards_; } 861 ZoneList<Guard*>* guards() { return guards_; }
845 862
846 private: 863 private:
847 RegExpNode* node_; 864 RegExpNode* node_;
848 ZoneList<Guard*>* guards_; 865 ZoneList<Guard*>* guards_;
849 }; 866 };
850 867
851 868
852 class ChoiceNode: public RegExpNode { 869 class ChoiceNode: public RegExpNode {
853 public: 870 public:
854 explicit ChoiceNode(int expected_size, RegExpNode* on_failure) 871 explicit ChoiceNode(int expected_size)
855 : on_failure_(on_failure), 872 : alternatives_(new ZoneList<GuardedAlternative>(expected_size)),
856 alternatives_(new ZoneList<GuardedAlternative>(expected_size)),
857 table_(NULL), 873 table_(NULL),
858 being_calculated_(false) { } 874 being_calculated_(false) { }
859 virtual void Accept(NodeVisitor* visitor); 875 virtual void Accept(NodeVisitor* visitor);
860 void AddAlternative(GuardedAlternative node) { alternatives()->Add(node); } 876 void AddAlternative(GuardedAlternative node) { alternatives()->Add(node); }
861 ZoneList<GuardedAlternative>* alternatives() { return alternatives_; } 877 ZoneList<GuardedAlternative>* alternatives() { return alternatives_; }
862 DispatchTable* GetTable(bool ignore_case); 878 DispatchTable* GetTable(bool ignore_case);
863 RegExpNode* on_failure() { return on_failure_; } 879 virtual bool Emit(RegExpCompiler* compiler, GenerationVariant* variant);
864 virtual bool Emit(RegExpCompiler* compiler);
865 virtual RegExpNode* PropagateForward(NodeInfo* info); 880 virtual RegExpNode* PropagateForward(NodeInfo* info);
866 virtual RegExpNode* ExpandLocal(NodeInfo* info); 881 virtual RegExpNode* ExpandLocal(NodeInfo* info);
867 virtual void ExpandChildren(); 882 virtual void ExpandChildren();
868 virtual ChoiceNode* Clone() { return new ChoiceNode(*this); } 883 virtual ChoiceNode* Clone() { return new ChoiceNode(*this); }
869 884
870 bool being_calculated() { return being_calculated_; } 885 bool being_calculated() { return being_calculated_; }
871 void set_being_calculated(bool b) { being_calculated_ = b; } 886 void set_being_calculated(bool b) { being_calculated_ = b; }
872 887
888 protected:
889 int GreedyLoopTextLength(GuardedAlternative *alternative);
890 ZoneList<GuardedAlternative>* alternatives_;
891
873 private: 892 private:
874 friend class DispatchTableConstructor; 893 friend class DispatchTableConstructor;
875 friend class Analysis; 894 friend class Analysis;
876 void GenerateGuard(RegExpMacroAssembler* macro_assembler, 895 void GenerateGuard(RegExpMacroAssembler* macro_assembler,
877 Guard *guard, 896 Guard *guard,
878 Label* on_failure); 897 GenerationVariant* variant);
879 RegExpNode* on_failure_;
880 ZoneList<GuardedAlternative>* alternatives_;
881 DispatchTable* table_; 898 DispatchTable* table_;
882 bool being_calculated_; 899 bool being_calculated_;
883 }; 900 };
884 901
885 902
903 class LoopChoiceNode: public ChoiceNode {
904 public:
905 explicit LoopChoiceNode(int expected_size) : ChoiceNode(expected_size) { }
906 virtual bool Emit(RegExpCompiler* compiler, GenerationVariant* variant);
907 virtual LoopChoiceNode* Clone() { return new LoopChoiceNode(*this); }
908 };
909
910
911 // There are many ways to generate code for a node. This class encapsulates
912 // the current way we should be generating. In other words it encapsulates
913 // the current state of the code generator.
914 class GenerationVariant {
Christian Plesner Hansen 2008/12/08 08:54:19 Not a fan of this name though I can't think of any
915 public:
916 class DeferredAction {
917 public:
918 DeferredAction(ActionNode::Type type, int reg)
919 : type_(type), reg_(reg), next_(NULL) { }
920 DeferredAction* next() { return next_; }
921 int reg() { return reg_; }
922 ActionNode::Type type() { return type_; }
923 private:
924 ActionNode::Type type_;
925 int reg_;
926 DeferredAction* next_;
927 friend class GenerationVariant;
928 };
929
930 class DeferredCapture: public DeferredAction {
931 public:
932 DeferredCapture(int reg, GenerationVariant* variant)
933 : DeferredAction(ActionNode::STORE_POSITION, reg),
934 cp_offset_(variant->cp_offset()) { }
935 int cp_offset() { return cp_offset_; }
936 private:
937 int cp_offset_;
938 void set_cp_offset(int cp_offset) { cp_offset_ = cp_offset; }
939 };
940
941 class DeferredSetRegister :public DeferredAction {
942 public:
943 DeferredSetRegister(int reg, int value)
944 : DeferredAction(ActionNode::SET_REGISTER, reg),
945 value_(value) { }
946 int value() { return value_; }
947 private:
948 int value_;
949 };
950
951 class DeferredIncrementRegister: public DeferredAction {
952 public:
953 explicit DeferredIncrementRegister(int reg)
954 : DeferredAction(ActionNode::INCREMENT_REGISTER, reg) { }
955 };
956
957 explicit GenerationVariant(Label* backtrack)
958 : cp_offset_(0),
959 actions_(NULL),
960 backtrack_(backtrack),
961 stop_node_(NULL),
962 loop_label_(NULL) { }
963 GenerationVariant()
964 : cp_offset_(0),
965 actions_(NULL),
966 backtrack_(NULL),
967 stop_node_(NULL),
968 loop_label_(NULL) { }
969 bool Flush(RegExpCompiler* compiler, RegExpNode* successor);
970 int cp_offset() { return cp_offset_; }
971 DeferredAction* actions() { return actions_; }
972 bool is_trivial() {
973 return backtrack_ == NULL && actions_ == NULL && cp_offset_ == 0;
974 }
975 Label* backtrack() { return backtrack_; }
976 Label* loop_label() { return loop_label_; }
977 RegExpNode* stop_node() { return stop_node_; }
978 // These set methods should be used only on new GenerationVariants - the
979 // intention is that GenerationVariants are immutable after creation.
980 void add_action(DeferredAction* new_action) {
981 ASSERT(new_action->next_ == NULL);
982 new_action->next_ = actions_;
983 actions_ = new_action;
984 }
985 void set_cp_offset(int new_cp_offset) {
986 ASSERT(new_cp_offset >= cp_offset_);
987 cp_offset_ = new_cp_offset;
988 }
989 void set_backtrack(Label* backtrack) { backtrack_ = backtrack; }
990 void set_stop_node(RegExpNode* node) { stop_node_ = node; }
991 void set_loop_label(Label* label) { loop_label_ = label; }
992 bool mentions_reg(int reg);
993 private:
994 int FindAffectedRegisters(OutSet* affected_registers);
995 void PerformDeferredActions(RegExpMacroAssembler* macro,
996 int max_register,
997 OutSet& affected_registers);
998 void RestoreAffectedRegisters(RegExpMacroAssembler* macro,
999 int max_register,
1000 OutSet& affected_registers);
1001 void PushAffectedRegisters(RegExpMacroAssembler* macro,
1002 int max_register,
1003 OutSet& affected_registers);
1004 int cp_offset_;
1005 DeferredAction* actions_;
1006 Label* backtrack_;
1007 RegExpNode* stop_node_;
1008 Label* loop_label_;
1009 };
886 class NodeVisitor { 1010 class NodeVisitor {
887 public: 1011 public:
888 virtual ~NodeVisitor() { } 1012 virtual ~NodeVisitor() { }
889 #define DECLARE_VISIT(Type) \ 1013 #define DECLARE_VISIT(Type) \
890 virtual void Visit##Type(Type##Node* that) = 0; 1014 virtual void Visit##Type(Type##Node* that) = 0;
891 FOR_EACH_NODE_TYPE(DECLARE_VISIT) 1015 FOR_EACH_NODE_TYPE(DECLARE_VISIT)
892 #undef DECLARE_VISIT 1016 #undef DECLARE_VISIT
893 }; 1017 };
894 1018
895 1019
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
949 Handle<String> error; 1073 Handle<String> error;
950 int capture_count; 1074 int capture_count;
951 }; 1075 };
952 1076
953 1077
954 class RegExpEngine: public AllStatic { 1078 class RegExpEngine: public AllStatic {
955 public: 1079 public:
956 static Handle<FixedArray> Compile(RegExpParseResult* input, 1080 static Handle<FixedArray> Compile(RegExpParseResult* input,
957 RegExpNode** node_return, 1081 RegExpNode** node_return,
958 bool ignore_case, 1082 bool ignore_case,
959 bool multiline); 1083 bool multiline,
1084 Handle<String> pattern);
960 static void DotPrint(const char* label, RegExpNode* node, bool ignore_case); 1085 static void DotPrint(const char* label, RegExpNode* node, bool ignore_case);
961 }; 1086 };
962 1087
963 1088
964 } } // namespace v8::internal 1089 } } // namespace v8::internal
965 1090
966 #endif // V8_JSREGEXP_H_ 1091 #endif // V8_JSREGEXP_H_
OLDNEW
« no previous file with comments | « src/interpreter-irregexp.cc ('k') | src/jsregexp.cc » ('j') | src/jsregexp.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698