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

Side by Side Diff: src/jsregexp.cc

Issue 10830: * We want to be able to find atoms and character classes without advancing th... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/regexp2000/
Patch Set: Created 12 years, 1 month 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 22 matching lines...) Expand all
33 #include "ast.h" 33 #include "ast.h"
34 #include "execution.h" 34 #include "execution.h"
35 #include "factory.h" 35 #include "factory.h"
36 #include "jsregexp-inl.h" 36 #include "jsregexp-inl.h"
37 #include "platform.h" 37 #include "platform.h"
38 #include "runtime.h" 38 #include "runtime.h"
39 #include "top.h" 39 #include "top.h"
40 #include "compilation-cache.h" 40 #include "compilation-cache.h"
41 #include "string-stream.h" 41 #include "string-stream.h"
42 #include "parser.h" 42 #include "parser.h"
43 #include "regexp-macro-assembler.h"
43 44
44 // Including pcre.h undefines DEBUG to avoid getting debug output from 45 // Including pcre.h undefines DEBUG to avoid getting debug output from
45 // the JSCRE implementation. Make sure to redefine it in debug mode 46 // the JSCRE implementation. Make sure to redefine it in debug mode
46 // after having included the header file. 47 // after having included the header file.
47 #ifdef DEBUG 48 #ifdef DEBUG
48 #include "third_party/jscre/pcre.h" 49 #include "third_party/jscre/pcre.h"
49 #define DEBUG 50 #define DEBUG
50 #else 51 #else
51 #include "third_party/jscre/pcre.h" 52 #include "third_party/jscre/pcre.h"
52 #endif 53 #endif
(...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after
625 ByteArray* RegExpImpl::JsreInternal(Handle<JSRegExp> re) { 626 ByteArray* RegExpImpl::JsreInternal(Handle<JSRegExp> re) {
626 FixedArray* value = FixedArray::cast(re->DataAt(JSRegExp::kJscreDataIndex)); 627 FixedArray* value = FixedArray::cast(re->DataAt(JSRegExp::kJscreDataIndex));
627 return ByteArray::cast(value->get(INTERNAL_INDEX)); 628 return ByteArray::cast(value->get(INTERNAL_INDEX));
628 } 629 }
629 630
630 631
631 // ------------------------------------------------------------------- 632 // -------------------------------------------------------------------
632 // New regular expression engine 633 // New regular expression engine
633 634
634 635
635 class ExecutionState; 636 class RegExpCompiler;
637 class DotPrinter;
636 638
637 639
638 class RegExpCompiler { 640 class RegExpCompiler {
639 public: 641 public:
640 explicit RegExpCompiler(int capture_count) 642 explicit RegExpCompiler(int capture_count)
641 : next_register_(2 * capture_count) { } 643 : next_register_(2 * capture_count),
644 work_list_(NULL) { }
642 645
643 RegExpNode* Compile(RegExpTree* tree, 646 RegExpNode* Compile(RegExpTree* tree,
644 RegExpNode* on_success, 647 RegExpNode* on_success,
645 RegExpNode* on_failure); 648 RegExpNode* on_failure);
646 649
647 int AllocateRegister() { return next_register_++; } 650 int AllocateRegister() { return next_register_++; }
648 651
652 Handle<FixedArray> Assemble(RegExpMacroAssembler* assembler,
653 RegExpNode* start);
654
655 inline void AddWork(RegExpNode* node) { work_list_->Add(node); }
656
657 static const int kImplementationOffset = 0;
658 static const int kNumberOfRegistersOffset = 0;
659 static const int kCodeOffset = 1;
660
661 RegExpMacroAssembler* macro_assembler() {
662 return macro_assembler_;
663 }
649 private: 664 private:
650 int next_register_; 665 int next_register_;
666 List<RegExpNode*>* work_list_;
667 RegExpMacroAssembler* macro_assembler_;
651 }; 668 };
652 669
653 670
671 Handle<FixedArray> RegExpCompiler::Assemble(
672 RegExpMacroAssembler* macro_assembler,
673 RegExpNode* start) {
674 macro_assembler_ = macro_assembler;
675 List <RegExpNode*> work_list(0);
676 work_list_ = &work_list;
677 start->GoTo(this);
678 while (!work_list.is_empty()) {
679 work_list.RemoveLast()->Emit(this);
680 }
681 Handle<FixedArray> array = Factory::NewFixedArray(3);
682 array->set(kImplementationOffset,
683 Smi::FromInt(macro_assembler->Implementation()),
684 SKIP_WRITE_BARRIER);
685 array->set(kNumberOfRegistersOffset,
686 Smi::FromInt(next_register_),
687 SKIP_WRITE_BARRIER);
688 Handle<Object> code = macro_assembler->GetCode();
689 work_list_ = NULL;
690 return array;
691 }
692
693
654 #define FOR_EACH_NODE_TYPE(VISIT) \ 694 #define FOR_EACH_NODE_TYPE(VISIT) \
655 VISIT(End) \ 695 VISIT(End) \
656 VISIT(Atom) \ 696 VISIT(Atom) \
657 VISIT(Action) \ 697 VISIT(Action) \
658 VISIT(Choice) \ 698 VISIT(Choice) \
659 VISIT(Backreference) \ 699 VISIT(Backreference) \
660 VISIT(CharacterClass) 700 VISIT(CharacterClass)
661 701
662 702
663 class RegExpNode: public ZoneObject { 703 void RegExpNode::GoTo(RegExpCompiler* compiler) {
664 public: 704 if (label.is_bound()) {
665 virtual ~RegExpNode() { } 705 compiler->macro_assembler()->GoTo(&label);
666 virtual void Accept(NodeVisitor* visitor) = 0; 706 } else {
667 }; 707 Emit(compiler);
708 }
709 }
710
711
712 void RegExpNode::EmitAddress(RegExpCompiler* compiler) {
713 compiler->macro_assembler()->EmitOrLink(&label);
714 }
668 715
669 716
670 class SeqRegExpNode: public RegExpNode { 717 class SeqRegExpNode: public RegExpNode {
671 public: 718 public:
672 explicit SeqRegExpNode(RegExpNode* on_success) 719 explicit SeqRegExpNode(RegExpNode* on_success)
673 : on_success_(on_success) { } 720 : on_success_(on_success) { }
674 RegExpNode* on_success() { return on_success_; } 721 RegExpNode* on_success() { return on_success_; }
722 virtual void Emit(RegExpCompiler* compiler) { UNREACHABLE(); }
675 private: 723 private:
676 RegExpNode* on_success_; 724 RegExpNode* on_success_;
677 }; 725 };
678 726
679 727
680 class EndNode: public RegExpNode { 728 class EndNode: public RegExpNode {
681 public: 729 public:
682 enum Action { ACCEPT, BACKTRACK }; 730 enum Action { ACCEPT, BACKTRACK };
683 virtual void Accept(NodeVisitor* visitor); 731 virtual void Accept(NodeVisitor* visitor);
684 static EndNode* GetAccept() { return &kAccept; } 732 static EndNode* GetAccept() { return &kAccept; }
685 static EndNode* GetBacktrack() { return &kBacktrack; } 733 static EndNode* GetBacktrack() { return &kBacktrack; }
734 virtual void Emit(RegExpCompiler* compiler) { UNREACHABLE(); }
686 private: 735 private:
687 explicit EndNode(Action action) : action_(action) { } 736 explicit EndNode(Action action) : action_(action) { }
688 Action action_; 737 Action action_;
689 static EndNode kAccept; 738 static EndNode kAccept;
690 static EndNode kBacktrack; 739 static EndNode kBacktrack;
691 }; 740 };
692 741
693 742
694 EndNode EndNode::kAccept(ACCEPT); 743 EndNode EndNode::kAccept(ACCEPT);
695 EndNode EndNode::kBacktrack(BACKTRACK); 744 EndNode EndNode::kBacktrack(BACKTRACK);
696 745
697 746
698 class AtomNode: public SeqRegExpNode { 747 class AtomNode: public SeqRegExpNode {
699 public: 748 public:
700 AtomNode(Vector<const uc16> data, 749 AtomNode(Vector<const uc16> data,
701 RegExpNode* on_success, 750 RegExpNode* on_success,
702 RegExpNode* on_failure) 751 RegExpNode* on_failure)
703 : SeqRegExpNode(on_success), 752 : SeqRegExpNode(on_success),
704 on_failure_(on_failure), 753 on_failure_(on_failure),
705 data_(data) { } 754 data_(data) { }
706 virtual void Accept(NodeVisitor* visitor); 755 virtual void Accept(NodeVisitor* visitor);
707 Vector<const uc16> data() { return data_; } 756 Vector<const uc16> data() { return data_; }
708 RegExpNode* on_failure() { return on_failure_; } 757 RegExpNode* on_failure() { return on_failure_; }
758 virtual void Emit(RegExpCompiler* compiler) { UNREACHABLE(); }
709 private: 759 private:
710 RegExpNode* on_failure_; 760 RegExpNode* on_failure_;
711 Vector<const uc16> data_; 761 Vector<const uc16> data_;
712 }; 762 };
713 763
714 764
715 class BackreferenceNode: public SeqRegExpNode { 765 class BackreferenceNode: public SeqRegExpNode {
716 public: 766 public:
717 BackreferenceNode(int start_reg, 767 BackreferenceNode(int start_reg,
718 int end_reg, 768 int end_reg,
719 RegExpNode* on_success, 769 RegExpNode* on_success,
720 RegExpNode* on_failure) 770 RegExpNode* on_failure)
721 : SeqRegExpNode(on_success), 771 : SeqRegExpNode(on_success),
722 on_failure_(on_failure), 772 on_failure_(on_failure),
723 start_reg_(start_reg), 773 start_reg_(start_reg),
724 end_reg_(end_reg) { } 774 end_reg_(end_reg) { }
725 virtual void Accept(NodeVisitor* visitor); 775 virtual void Accept(NodeVisitor* visitor);
726 RegExpNode* on_failure() { return on_failure_; } 776 RegExpNode* on_failure() { return on_failure_; }
727 int start_register() { return start_reg_; } 777 int start_register() { return start_reg_; }
728 int end_register() { return end_reg_; } 778 int end_register() { return end_reg_; }
779 virtual void Emit(RegExpCompiler* compiler) { UNREACHABLE(); }
729 private: 780 private:
730 RegExpNode* on_failure_; 781 RegExpNode* on_failure_;
731 int start_reg_; 782 int start_reg_;
732 int end_reg_; 783 int end_reg_;
733 }; 784 };
734 785
735 786
736 class CharacterClassNode: public SeqRegExpNode { 787 class CharacterClassNode: public SeqRegExpNode {
737 public: 788 public:
738 CharacterClassNode(ZoneList<CharacterRange>* ranges, 789 CharacterClassNode(ZoneList<CharacterRange>* ranges,
739 bool is_negated, 790 bool is_negated,
740 RegExpNode* on_success, 791 RegExpNode* on_success,
741 RegExpNode* on_failure) 792 RegExpNode* on_failure)
742 : SeqRegExpNode(on_success), 793 : SeqRegExpNode(on_success),
743 on_failure_(on_failure), 794 on_failure_(on_failure),
744 ranges_(ranges), 795 ranges_(ranges),
745 is_negated_(is_negated ){ } 796 is_negated_(is_negated ) { }
746 virtual void Accept(NodeVisitor* visitor); 797 virtual void Accept(NodeVisitor* visitor);
747 ZoneList<CharacterRange>* ranges() { return ranges_; } 798 ZoneList<CharacterRange>* ranges() { return ranges_; }
748 bool is_negated() { return is_negated_; } 799 bool is_negated() { return is_negated_; }
749 RegExpNode* on_failure() { return on_failure_; } 800 RegExpNode* on_failure() { return on_failure_; }
801 virtual void Emit(RegExpCompiler* compiler) { UNREACHABLE(); }
750 static void AddInverseToTable(List<CharacterRange> ranges, 802 static void AddInverseToTable(List<CharacterRange> ranges,
751 DispatchTable* table, 803 DispatchTable* table,
752 int index); 804 int index);
753 private: 805 private:
754 RegExpNode* on_failure_; 806 RegExpNode* on_failure_;
755 ZoneList<CharacterRange>* ranges_; 807 ZoneList<CharacterRange>* ranges_;
756 bool is_negated_; 808 bool is_negated_;
757 }; 809 };
758 810
759 811
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
797 public: 849 public:
798 explicit ChoiceNode(int expected_size, RegExpNode* on_failure) 850 explicit ChoiceNode(int expected_size, RegExpNode* on_failure)
799 : on_failure_(on_failure), 851 : on_failure_(on_failure),
800 choices_(new ZoneList<GuardedAlternative>(expected_size)), 852 choices_(new ZoneList<GuardedAlternative>(expected_size)),
801 visited_(false) { } 853 visited_(false) { }
802 virtual void Accept(NodeVisitor* visitor); 854 virtual void Accept(NodeVisitor* visitor);
803 void AddChild(GuardedAlternative node) { choices()->Add(node); } 855 void AddChild(GuardedAlternative node) { choices()->Add(node); }
804 ZoneList<GuardedAlternative>* choices() { return choices_; } 856 ZoneList<GuardedAlternative>* choices() { return choices_; }
805 DispatchTable* table() { return &table_; } 857 DispatchTable* table() { return &table_; }
806 RegExpNode* on_failure() { return on_failure_; } 858 RegExpNode* on_failure() { return on_failure_; }
859 virtual void Emit(RegExpCompiler* compiler);
807 bool visited() { return visited_; } 860 bool visited() { return visited_; }
808 void set_visited(bool value) { visited_ = value; } 861 void set_visited(bool value) { visited_ = value; }
809 private: 862 private:
810 RegExpNode* on_failure_; 863 RegExpNode* on_failure_;
811 ZoneList<GuardedAlternative>* choices_; 864 ZoneList<GuardedAlternative>* choices_;
812 DispatchTable table_; 865 DispatchTable table_;
813 bool visited_; 866 bool visited_;
814 }; 867 };
815 868
816 869
817 class ActionNode: public SeqRegExpNode { 870 class ActionNode: public SeqRegExpNode {
818 public: 871 public:
819 enum Type { 872 enum Type {
820 STORE_REGISTER, 873 STORE_REGISTER,
821 INCREMENT_REGISTER, 874 INCREMENT_REGISTER,
822 STORE_POSITION, 875 STORE_POSITION,
823 RESTORE_POSITION, 876 RESTORE_POSITION,
824 BEGIN_SUBMATCH, 877 BEGIN_SUBMATCH,
825 ESCAPE_SUBMATCH, 878 ESCAPE_SUBMATCH,
826 END_SUBMATCH 879 END_SUBMATCH
827 }; 880 };
828 static ActionNode* StoreRegister(int reg, int val, RegExpNode* on_success); 881 static ActionNode* StoreRegister(int reg, int val, RegExpNode* on_success);
829 static ActionNode* IncrementRegister(int reg, RegExpNode* on_success); 882 static ActionNode* IncrementRegister(int reg, RegExpNode* on_success);
830 static ActionNode* StorePosition(int reg, RegExpNode* on_success); 883 static ActionNode* StorePosition(int reg, RegExpNode* on_success);
831 static ActionNode* RestorePosition(int reg, RegExpNode* on_success); 884 static ActionNode* RestorePosition(int reg, RegExpNode* on_success);
832 static ActionNode* BeginSubmatch(RegExpNode* on_success); 885 static ActionNode* BeginSubmatch(RegExpNode* on_success);
833 static ActionNode* EscapeSubmatch(RegExpNode* on_success); 886 static ActionNode* EscapeSubmatch(RegExpNode* on_success);
834 static ActionNode* EndSubmatch(RegExpNode* on_success); 887 static ActionNode* EndSubmatch(RegExpNode* on_success);
835 virtual void Accept(NodeVisitor* visitor); 888 virtual void Accept(NodeVisitor* visitor);
836 Type type; 889 virtual void Emit(RegExpCompiler* compiler);
890 private:
837 union { 891 union {
838 struct { 892 struct {
839 int reg; 893 int reg;
840 int value; 894 int value;
841 } u_store_register; 895 } u_store_register;
842 struct { 896 struct {
843 int reg; 897 int reg;
844 } u_increment_register; 898 } u_increment_register;
845 struct { 899 struct {
846 int reg; 900 int reg;
847 } u_position_register; 901 } u_position_register;
848 } data; 902 } data_;
849 private: 903 ActionNode(Type type, RegExpNode* on_success)
850 ActionNode(Type _type, RegExpNode* on_success)
851 : SeqRegExpNode(on_success), 904 : SeqRegExpNode(on_success),
852 type(_type) { } 905 type_(type) { }
906 Type type_;
907 friend class DotPrinter;
853 }; 908 };
854 909
855 910
856 ActionNode* ActionNode::StoreRegister(int reg, 911 ActionNode* ActionNode::StoreRegister(int reg,
857 int val, 912 int val,
858 RegExpNode* on_success) { 913 RegExpNode* on_success) {
859 ActionNode* result = new ActionNode(STORE_REGISTER, on_success); 914 ActionNode* result = new ActionNode(STORE_REGISTER, on_success);
860 result->data.u_store_register.reg = reg; 915 result->data_.u_store_register.reg = reg;
861 result->data.u_store_register.value = val; 916 result->data_.u_store_register.value = val;
862 return result; 917 return result;
863 } 918 }
864 919
865 920
866 ActionNode* ActionNode::IncrementRegister(int reg, RegExpNode* on_success) { 921 ActionNode* ActionNode::IncrementRegister(int reg, RegExpNode* on_success) {
867 ActionNode* result = new ActionNode(INCREMENT_REGISTER, on_success); 922 ActionNode* result = new ActionNode(INCREMENT_REGISTER, on_success);
868 result->data.u_increment_register.reg = reg; 923 result->data_.u_increment_register.reg = reg;
869 return result; 924 return result;
870 } 925 }
871 926
872 927
873 ActionNode* ActionNode::StorePosition(int reg, RegExpNode* on_success) { 928 ActionNode* ActionNode::StorePosition(int reg, RegExpNode* on_success) {
874 ActionNode* result = new ActionNode(STORE_POSITION, on_success); 929 ActionNode* result = new ActionNode(STORE_POSITION, on_success);
875 result->data.u_position_register.reg = reg; 930 result->data_.u_position_register.reg = reg;
876 return result; 931 return result;
877 } 932 }
878 933
879 934
880 ActionNode* ActionNode::RestorePosition(int reg, RegExpNode* on_success) { 935 ActionNode* ActionNode::RestorePosition(int reg, RegExpNode* on_success) {
881 ActionNode* result = new ActionNode(RESTORE_POSITION, on_success); 936 ActionNode* result = new ActionNode(RESTORE_POSITION, on_success);
882 result->data.u_position_register.reg = reg; 937 result->data_.u_position_register.reg = reg;
883 return result; 938 return result;
884 } 939 }
885 940
886 941
887 ActionNode* ActionNode::BeginSubmatch(RegExpNode* on_success) { 942 ActionNode* ActionNode::BeginSubmatch(RegExpNode* on_success) {
888 return new ActionNode(BEGIN_SUBMATCH, on_success); 943 return new ActionNode(BEGIN_SUBMATCH, on_success);
889 } 944 }
890 945
891 946
892 ActionNode* ActionNode::EscapeSubmatch(RegExpNode* on_success) { 947 ActionNode* ActionNode::EscapeSubmatch(RegExpNode* on_success) {
(...skipping 18 matching lines...) Expand all
911 966
912 #define DEFINE_ACCEPT(Type) \ 967 #define DEFINE_ACCEPT(Type) \
913 void Type##Node::Accept(NodeVisitor* visitor) { \ 968 void Type##Node::Accept(NodeVisitor* visitor) { \
914 visitor->Visit##Type(this); \ 969 visitor->Visit##Type(this); \
915 } 970 }
916 FOR_EACH_NODE_TYPE(DEFINE_ACCEPT) 971 FOR_EACH_NODE_TYPE(DEFINE_ACCEPT)
917 #undef DEFINE_ACCEPT 972 #undef DEFINE_ACCEPT
918 973
919 974
920 // ------------------------------------------------------------------- 975 // -------------------------------------------------------------------
976 // Emit code.
977
978
979 void ChoiceNode::Emit(RegExpCompiler* compiler) {
980 // TODO(erikcorry): Implement this.
981 UNREACHABLE();
982 }
983
984
985 void ActionNode::Emit(RegExpCompiler* compiler) {
986 RegExpMacroAssembler* macro = compiler->macro_assembler();
987 switch (type_) {
988 case STORE_REGISTER:
989 macro->SetRegister(data_.u_store_register.reg,
990 data_.u_store_register.value);
991 break;
992 case INCREMENT_REGISTER:
993 macro->AdvanceRegister(data_.u_increment_register.reg, 1);
994 break;
995 case STORE_POSITION:
996 macro->PushCurrentPosition();
997 break;
998 case RESTORE_POSITION:
999 macro->PopCurrentPosition();
1000 break;
1001 case BEGIN_SUBMATCH:
1002 // TODO(erikcorry): Implement this.
1003 UNREACHABLE();
1004 break;
1005 case ESCAPE_SUBMATCH:
1006 // TODO(erikcorry): Implement this.
1007 UNREACHABLE();
1008 break;
1009 case END_SUBMATCH:
1010 // TODO(erikcorry): Implement this.
1011 UNREACHABLE();
1012 break;
1013 }
1014 }
1015
1016
1017 // -------------------------------------------------------------------
921 // Dot/dotty output 1018 // Dot/dotty output
922 1019
923 1020
924 #ifdef DEBUG 1021 #ifdef DEBUG
925 1022
926 1023
927 class DotPrinter: public NodeVisitor { 1024 class DotPrinter: public NodeVisitor {
928 public: 1025 public:
929 DotPrinter() : stream_(&alloc_) { } 1026 DotPrinter() : stream_(&alloc_) { }
930 void PrintNode(const char* label, RegExpNode* node); 1027 void PrintNode(const char* label, RegExpNode* node);
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
1041 void DotPrinter::VisitCharacterClass(CharacterClassNode* that) { 1138 void DotPrinter::VisitCharacterClass(CharacterClassNode* that) {
1042 stream()->Add(" n%p [label=\"[...]\"];\n", that); 1139 stream()->Add(" n%p [label=\"[...]\"];\n", that);
1043 stream()->Add(" n%p -> n%p;\n", that, that->on_success()); 1140 stream()->Add(" n%p -> n%p;\n", that, that->on_success());
1044 Visit(that->on_success()); 1141 Visit(that->on_success());
1045 PrintOnFailure(that, that->on_failure()); 1142 PrintOnFailure(that, that->on_failure());
1046 } 1143 }
1047 1144
1048 1145
1049 void DotPrinter::VisitAction(ActionNode* that) { 1146 void DotPrinter::VisitAction(ActionNode* that) {
1050 stream()->Add(" n%p [", that); 1147 stream()->Add(" n%p [", that);
1051 switch (that->type) { 1148 switch (that->type_) {
1052 case ActionNode::STORE_REGISTER: 1149 case ActionNode::STORE_REGISTER:
1053 stream()->Add("label=\"$%i:=%i\", shape=box", 1150 stream()->Add("label=\"$%i:=%i\", shape=box",
1054 that->data.u_store_register.reg, 1151 that->data_.u_store_register.reg,
1055 that->data.u_store_register.value); 1152 that->data_.u_store_register.value);
1056 break; 1153 break;
1057 case ActionNode::INCREMENT_REGISTER: 1154 case ActionNode::INCREMENT_REGISTER:
1058 stream()->Add("label=\"$%i++\", shape=box", 1155 stream()->Add("label=\"$%i++\", shape=box",
1059 that->data.u_increment_register.reg); 1156 that->data_.u_increment_register.reg);
1060 break; 1157 break;
1061 case ActionNode::STORE_POSITION: 1158 case ActionNode::STORE_POSITION:
1062 stream()->Add("label=\"$%i:=$pos\", shape=box", 1159 stream()->Add("label=\"$%i:=$pos\", shape=box",
1063 that->data.u_position_register.reg); 1160 that->data_.u_position_register.reg);
1064 break; 1161 break;
1065 case ActionNode::RESTORE_POSITION: 1162 case ActionNode::RESTORE_POSITION:
1066 stream()->Add("label=\"$pos:=$%i\", shape=box", 1163 stream()->Add("label=\"$pos:=$%i\", shape=box",
1067 that->data.u_position_register.reg); 1164 that->data_.u_position_register.reg);
1068 break; 1165 break;
1069 case ActionNode::BEGIN_SUBMATCH: 1166 case ActionNode::BEGIN_SUBMATCH:
1070 stream()->Add("label=\"begin\", shape=septagon"); 1167 stream()->Add("label=\"begin\", shape=septagon");
1071 break; 1168 break;
1072 case ActionNode::ESCAPE_SUBMATCH: 1169 case ActionNode::ESCAPE_SUBMATCH:
1073 stream()->Add("label=\"escape\", shape=septagon"); 1170 stream()->Add("label=\"escape\", shape=septagon");
1074 break; 1171 break;
1075 case ActionNode::END_SUBMATCH: 1172 case ActionNode::END_SUBMATCH:
1076 stream()->Add("label=\"end\", shape=septagon"); 1173 stream()->Add("label=\"end\", shape=septagon");
1077 break; 1174 break;
1078 } 1175 }
1079 stream()->Add("];\n"); 1176 stream()->Add("];\n");
1080 stream()->Add(" n%p -> n%p;\n", that, that->on_success()); 1177 stream()->Add(" n%p -> n%p;\n", that, that->on_success());
1081 Visit(that->on_success()); 1178 Visit(that->on_success());
1082 } 1179 }
1083 1180
1084 1181
1085 class DispatchTableDumper { 1182 class DispatchTableDumper {
1086 public: 1183 public:
1087 DispatchTableDumper(StringStream* stream) : stream_(stream) { } 1184 explicit DispatchTableDumper(StringStream* stream) : stream_(stream) { }
1088 void Call(uc16 key, DispatchTable::Entry entry); 1185 void Call(uc16 key, DispatchTable::Entry entry);
1089 StringStream* stream() { return stream_; } 1186 StringStream* stream() { return stream_; }
1090 private: 1187 private:
1091 StringStream* stream_; 1188 StringStream* stream_;
1092 }; 1189 };
1093 1190
1094 1191
1095 void DispatchTableDumper::Call(uc16 key, DispatchTable::Entry entry) { 1192 void DispatchTableDumper::Call(uc16 key, DispatchTable::Entry entry) {
1096 stream()->Add("[%k-%k]: {", key, entry.to()); 1193 stream()->Add("[%k-%k]: {", key, entry.to());
1097 OutSet* set = entry.out_set(); 1194 OutSet* set = entry.out_set();
1098 bool first = true; 1195 bool first = true;
1099 for (unsigned i = 0; i < OutSet::kFirstLimit; i++) { 1196 for (unsigned i = 0; i < OutSet::kFirstLimit; i++) {
1100 if (set->Get(i)) { 1197 if (set->Get(i)) {
1101 if (first) first = false; 1198 if (first) {
1102 else stream()->Add(", "); 1199 first = false;
1200 } else {
1201 stream()->Add(", ");
1202 }
1103 stream()->Add("%i", i); 1203 stream()->Add("%i", i);
1104 } 1204 }
1105 } 1205 }
1106 stream()->Add("}\n"); 1206 stream()->Add("}\n");
1107 } 1207 }
1108 1208
1109 1209
1110 void DispatchTable::Dump() { 1210 void DispatchTable::Dump() {
1111 HeapStringAllocator alloc; 1211 HeapStringAllocator alloc;
1112 StringStream stream(&alloc); 1212 StringStream stream(&alloc);
1113 tree()->ForEach(DispatchTableDumper(&stream)); 1213 tree()->ForEach(DispatchTableDumper(&stream));
1114 OS::PrintError("%s", *stream.ToCString()); 1214 OS::PrintError("%s", *stream.ToCString());
1115 } 1215 }
1116 1216
1117 1217
1118 void RegExpEngine::DotPrint(const char* label, RegExpNode* node) { 1218 void RegExpEngine::DotPrint(const char* label, RegExpNode* node) {
1119 DotPrinter printer; 1219 DotPrinter printer;
1120 printer.PrintNode(label, node); 1220 printer.PrintNode(label, node);
1121 } 1221 }
1122 1222
1123 1223
1124 #endif // DEBUG 1224 #endif // DEBUG
1125 1225
1126 1226
1127 // ------------------------------------------------------------------- 1227 // -------------------------------------------------------------------
1128 // Tree to graph conversion 1228 // Tree to graph conversion
1129 1229
1130 1230
1131 RegExpNode* RegExpAtom::ToNode(RegExpCompiler* compiler, 1231 RegExpNode* RegExpAtom::ToNode(RegExpCompiler* compiler,
1132 RegExpNode* on_success, 1232 RegExpNode* on_success,
1133 RegExpNode* on_failure) { 1233 RegExpNode* on_failure) {
1134 return new AtomNode(data(), on_success, on_failure); 1234 return new AtomNode(data(), on_success, on_failure);
(...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after
1521 return empty(); 1621 return empty();
1522 } 1622 }
1523 1623
1524 1624
1525 // ------------------------------------------------------------------- 1625 // -------------------------------------------------------------------
1526 // Analysis 1626 // Analysis
1527 1627
1528 1628
1529 class Analysis: public NodeVisitor { 1629 class Analysis: public NodeVisitor {
1530 public: 1630 public:
1531 Analysis(RegExpCompiler* compiler) 1631 explicit Analysis(RegExpCompiler* compiler)
1532 : compiler_(compiler), 1632 : compiler_(compiler),
1533 table_(NULL), 1633 table_(NULL),
1534 choice_index_(-1) { } 1634 choice_index_(-1) { }
1535 DispatchTable* table() { return table_; } 1635 DispatchTable* table() { return table_; }
1536 RegExpCompiler* compiler() { return compiler_; } 1636 RegExpCompiler* compiler() { return compiler_; }
1537 int choice_index() { return choice_index_; } 1637 int choice_index() { return choice_index_; }
1538 void Analyze(RegExpNode* node) { node->Accept(this); } 1638 void Analyze(RegExpNode* node) { node->Accept(this); }
1539 #define DECLARE_VISIT(Type) \ 1639 #define DECLARE_VISIT(Type) \
1540 virtual void Visit##Type(Type##Node* that); 1640 virtual void Visit##Type(Type##Node* that);
1541 FOR_EACH_NODE_TYPE(DECLARE_VISIT) 1641 FOR_EACH_NODE_TYPE(DECLARE_VISIT)
1542 #undef DECLARE_VISIT 1642 #undef DECLARE_VISIT
1543 protected: 1643 protected:
1544 Analysis(Analysis* prev) { *this = *prev; } 1644 explicit Analysis(Analysis* prev) { *this = *prev; }
1545 RegExpCompiler* compiler_; 1645 RegExpCompiler* compiler_;
1546 DispatchTable *table_; 1646 DispatchTable *table_;
1547 int choice_index_; 1647 int choice_index_;
1548 }; 1648 };
1549 1649
1550 1650
1551 // A subclass of analysis data that allows fields to be set. Anyone 1651 // A subclass of analysis data that allows fields to be set. Anyone
1552 // who needs to create new analysis data creates an instance of this 1652 // who needs to create new analysis data creates an instance of this
1553 // class, configures it, and then passes it on as an AnalysisData 1653 // class, configures it, and then passes it on as an AnalysisData
1554 // which doesn't allow its fields to be changed. 1654 // which doesn't allow its fields to be changed.
1555 class AnalysisBuilder: public Analysis { 1655 class AnalysisBuilder: public Analysis {
1556 public: 1656 public:
1557 AnalysisBuilder(Analysis* prev) : Analysis(prev) { } 1657 explicit AnalysisBuilder(Analysis* prev) : Analysis(prev) { }
1558 void set_table(DispatchTable* value) { table_ = value; } 1658 void set_table(DispatchTable* value) { table_ = value; }
1559 void set_choice_index(int value) { choice_index_ = value; } 1659 void set_choice_index(int value) { choice_index_ = value; }
1560 }; 1660 };
1561 1661
1562 1662
1563 void Analysis::VisitEnd(EndNode* that) { 1663 void Analysis::VisitEnd(EndNode* that) {
1564 // nothing to do 1664 // nothing to do
1565 } 1665 }
1566 1666
1567 1667
1568 class AddDispatchRange { 1668 class AddDispatchRange {
1569 public: 1669 public:
1570 AddDispatchRange(Analysis* analysis) : analysis_(analysis) { } 1670 explicit AddDispatchRange(Analysis* analysis) : analysis_(analysis) { }
1571 void Call(uc32 from, DispatchTable::Entry entry); 1671 void Call(uc32 from, DispatchTable::Entry entry);
1572 private: 1672 private:
1573 Analysis* analysis_; 1673 Analysis* analysis_;
1574 }; 1674 };
1575 1675
1576 1676
1577 void AddDispatchRange::Call(uc32 from, DispatchTable::Entry entry) { 1677 void AddDispatchRange::Call(uc32 from, DispatchTable::Entry entry) {
1578 CharacterRange range(from, entry.to()); 1678 CharacterRange range(from, entry.to());
1579 analysis_->table()->AddRange(range, analysis_->choice_index()); 1679 analysis_->table()->AddRange(range, analysis_->choice_index());
1580 } 1680 }
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1645 1745
1646 RegExpNode* RegExpEngine::Compile(RegExpParseResult* input) { 1746 RegExpNode* RegExpEngine::Compile(RegExpParseResult* input) {
1647 RegExpCompiler compiler(input->capture_count); 1747 RegExpCompiler compiler(input->capture_count);
1648 RegExpNode* node = compiler.Compile(input->tree, 1748 RegExpNode* node = compiler.Compile(input->tree,
1649 EndNode::GetAccept(), 1749 EndNode::GetAccept(),
1650 EndNode::GetBacktrack()); 1750 EndNode::GetBacktrack());
1651 return node; 1751 return node;
1652 } 1752 }
1653 1753
1654 1754
1755 RegExpMacroAssembler::~RegExpMacroAssembler() {
1756 }
1757
1758
1655 }} // namespace v8::internal 1759 }} // namespace v8::internal
OLDNEW
« no previous file with comments | « src/jsregexp.h ('k') | src/regexp-macro-assembler.h » ('j') | src/regexp-macro-assembler.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698