Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 646 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 657 virtual RegExpNode* Clone() = 0; | 657 virtual RegExpNode* Clone() = 0; |
| 658 | 658 |
| 659 private: | 659 private: |
| 660 Label label_; | 660 Label label_; |
| 661 NodeInfo info_; | 661 NodeInfo info_; |
| 662 SiblingList siblings_; | 662 SiblingList siblings_; |
| 663 int variants_generated_; | 663 int variants_generated_; |
| 664 }; | 664 }; |
| 665 | 665 |
| 666 | 666 |
| 667 // A simple closed interval. | |
| 668 class Interval { | |
| 669 public: | |
| 670 Interval() : from_(kNone), to_(kNone) { } | |
| 671 Interval(short from, short to) : from_(from), to_(to) { } | |
| 672 Interval Union(Interval that) { | |
| 673 if (that.from_ == kNone) return *this; | |
| 674 else if (from_ == kNone) return that; | |
| 675 else return Interval(Min(from_, that.from_), Max(to_, that.to_)); | |
| 676 } | |
| 677 bool Contains(int value) { | |
| 678 return (from_ <= value) && (value <= to_); | |
| 679 } | |
| 680 bool is_empty() { return from_ == kNone; } | |
| 681 short from() { return from_; } | |
| 682 short to() { return to_; } | |
| 683 static Interval Empty() { return Interval(); } | |
| 684 static const int kNone = -1; | |
| 685 private: | |
| 686 short from_; | |
| 687 short to_; | |
| 688 }; | |
| 689 | |
| 690 | |
| 667 class SeqRegExpNode: public RegExpNode { | 691 class SeqRegExpNode: public RegExpNode { |
| 668 public: | 692 public: |
| 669 explicit SeqRegExpNode(RegExpNode* on_success) | 693 explicit SeqRegExpNode(RegExpNode* on_success) |
| 670 : on_success_(on_success) { } | 694 : on_success_(on_success) { } |
| 671 RegExpNode* on_success() { return on_success_; } | 695 RegExpNode* on_success() { return on_success_; } |
| 672 void set_on_success(RegExpNode* node) { on_success_ = node; } | 696 void set_on_success(RegExpNode* node) { on_success_ = node; } |
| 673 private: | 697 private: |
| 674 RegExpNode* on_success_; | 698 RegExpNode* on_success_; |
| 675 }; | 699 }; |
| 676 | 700 |
| 677 | 701 |
| 678 class ActionNode: public SeqRegExpNode { | 702 class ActionNode: public SeqRegExpNode { |
| 679 public: | 703 public: |
| 680 enum Type { | 704 enum Type { |
| 681 SET_REGISTER, | 705 SET_REGISTER, |
| 682 INCREMENT_REGISTER, | 706 INCREMENT_REGISTER, |
| 683 STORE_POSITION, | 707 STORE_POSITION, |
| 684 BEGIN_SUBMATCH, | 708 BEGIN_SUBMATCH, |
| 685 POSITIVE_SUBMATCH_SUCCESS, | 709 POSITIVE_SUBMATCH_SUCCESS, |
| 686 EMPTY_MATCH_CHECK | 710 EMPTY_MATCH_CHECK, |
| 711 CLEAR_CAPTURES | |
| 687 }; | 712 }; |
| 688 static ActionNode* SetRegister(int reg, int val, RegExpNode* on_success); | 713 static ActionNode* SetRegister(int reg, int val, RegExpNode* on_success); |
| 689 static ActionNode* IncrementRegister(int reg, RegExpNode* on_success); | 714 static ActionNode* IncrementRegister(int reg, RegExpNode* on_success); |
| 690 static ActionNode* StorePosition(int reg, RegExpNode* on_success); | 715 static ActionNode* StorePosition(int reg, RegExpNode* on_success); |
| 691 static ActionNode* BeginSubmatch( | 716 static ActionNode* ClearCaptures(Interval range, |
| 692 int stack_pointer_reg, | 717 RegExpNode* on_success); |
|
Erik Corry
2009/01/14 09:24:31
This fits on one line.
Christian Plesner Hansen
2009/01/14 11:31:35
Fixed
| |
| 693 int position_reg, | 718 static ActionNode* BeginSubmatch(int stack_pointer_reg, |
| 694 RegExpNode* on_success); | 719 int position_reg, |
| 695 static ActionNode* PositiveSubmatchSuccess( | 720 RegExpNode* on_success); |
| 696 int stack_pointer_reg, | 721 static ActionNode* PositiveSubmatchSuccess(int stack_pointer_reg, |
| 697 int restore_reg, | 722 int restore_reg, |
| 698 RegExpNode* on_success); | 723 RegExpNode* on_success); |
| 699 static ActionNode* EmptyMatchCheck( | 724 static ActionNode* EmptyMatchCheck(int start_register, |
| 700 int start_register, | 725 int repetition_register, |
| 701 int repetition_register, | 726 int repetition_limit, |
| 702 int repetition_limit, | 727 RegExpNode* on_success); |
| 703 RegExpNode* on_success); | |
| 704 virtual void Accept(NodeVisitor* visitor); | 728 virtual void Accept(NodeVisitor* visitor); |
| 705 virtual bool Emit(RegExpCompiler* compiler, GenerationVariant* variant); | 729 virtual bool Emit(RegExpCompiler* compiler, GenerationVariant* variant); |
| 706 virtual int EatsAtLeast(int recursion_depth); | 730 virtual int EatsAtLeast(int recursion_depth); |
| 707 virtual void GetQuickCheckDetails(QuickCheckDetails* details, | 731 virtual void GetQuickCheckDetails(QuickCheckDetails* details, |
| 708 RegExpCompiler* compiler, | 732 RegExpCompiler* compiler, |
| 709 int filled_in) { | 733 int filled_in) { |
| 710 return on_success()->GetQuickCheckDetails(details, compiler, filled_in); | 734 return on_success()->GetQuickCheckDetails(details, compiler, filled_in); |
| 711 } | 735 } |
| 712 virtual RegExpNode* PropagateForward(NodeInfo* info); | 736 virtual RegExpNode* PropagateForward(NodeInfo* info); |
| 713 Type type() { return type_; } | 737 Type type() { return type_; } |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 729 } u_position_register; | 753 } u_position_register; |
| 730 struct { | 754 struct { |
| 731 int stack_pointer_register; | 755 int stack_pointer_register; |
| 732 int current_position_register; | 756 int current_position_register; |
| 733 } u_submatch; | 757 } u_submatch; |
| 734 struct { | 758 struct { |
| 735 int start_register; | 759 int start_register; |
| 736 int repetition_register; | 760 int repetition_register; |
| 737 int repetition_limit; | 761 int repetition_limit; |
| 738 } u_empty_match_check; | 762 } u_empty_match_check; |
| 763 struct { | |
| 764 int range_from; | |
|
Erik Corry
2009/01/14 09:24:31
Can't we just have an Interval here?
Christian Plesner Hansen
2009/01/14 11:31:35
I thought so too but it turns out that you can't h
| |
| 765 int range_to; | |
| 766 } u_clear_captures; | |
| 739 } data_; | 767 } data_; |
| 740 ActionNode(Type type, RegExpNode* on_success) | 768 ActionNode(Type type, RegExpNode* on_success) |
| 741 : SeqRegExpNode(on_success), | 769 : SeqRegExpNode(on_success), |
| 742 type_(type) { } | 770 type_(type) { } |
| 743 Type type_; | 771 Type type_; |
| 744 friend class DotPrinter; | 772 friend class DotPrinter; |
| 745 }; | 773 }; |
| 746 | 774 |
| 747 | 775 |
| 748 class TextNode: public SeqRegExpNode { | 776 class TextNode: public SeqRegExpNode { |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 973 // There are many ways to generate code for a node. This class encapsulates | 1001 // There are many ways to generate code for a node. This class encapsulates |
| 974 // the current way we should be generating. In other words it encapsulates | 1002 // the current way we should be generating. In other words it encapsulates |
| 975 // the current state of the code generator. | 1003 // the current state of the code generator. |
| 976 class GenerationVariant { | 1004 class GenerationVariant { |
| 977 public: | 1005 public: |
| 978 class DeferredAction { | 1006 class DeferredAction { |
| 979 public: | 1007 public: |
| 980 DeferredAction(ActionNode::Type type, int reg) | 1008 DeferredAction(ActionNode::Type type, int reg) |
| 981 : type_(type), reg_(reg), next_(NULL) { } | 1009 : type_(type), reg_(reg), next_(NULL) { } |
| 982 DeferredAction* next() { return next_; } | 1010 DeferredAction* next() { return next_; } |
| 1011 bool Mentions(int reg); | |
|
Erik Corry
2009/01/14 09:24:31
It's messy that this is not a private method, sinc
Christian Plesner Hansen
2009/01/14 11:31:35
I'm not sure -- all other operations than the one
| |
| 983 int reg() { return reg_; } | 1012 int reg() { return reg_; } |
| 984 ActionNode::Type type() { return type_; } | 1013 ActionNode::Type type() { return type_; } |
| 985 private: | 1014 private: |
| 986 ActionNode::Type type_; | 1015 ActionNode::Type type_; |
| 987 int reg_; | 1016 int reg_; |
| 988 DeferredAction* next_; | 1017 DeferredAction* next_; |
| 989 friend class GenerationVariant; | 1018 friend class GenerationVariant; |
| 990 }; | 1019 }; |
| 991 | 1020 |
| 992 class DeferredCapture: public DeferredAction { | 1021 class DeferredCapture: public DeferredAction { |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 1003 class DeferredSetRegister :public DeferredAction { | 1032 class DeferredSetRegister :public DeferredAction { |
| 1004 public: | 1033 public: |
| 1005 DeferredSetRegister(int reg, int value) | 1034 DeferredSetRegister(int reg, int value) |
| 1006 : DeferredAction(ActionNode::SET_REGISTER, reg), | 1035 : DeferredAction(ActionNode::SET_REGISTER, reg), |
| 1007 value_(value) { } | 1036 value_(value) { } |
| 1008 int value() { return value_; } | 1037 int value() { return value_; } |
| 1009 private: | 1038 private: |
| 1010 int value_; | 1039 int value_; |
| 1011 }; | 1040 }; |
| 1012 | 1041 |
| 1042 class DeferredClearCaptures : public DeferredAction { | |
| 1043 public: | |
| 1044 DeferredClearCaptures(Interval range) | |
| 1045 : DeferredAction(ActionNode::CLEAR_CAPTURES, -1), | |
| 1046 range_(range) { } | |
| 1047 Interval range() { return range_; } | |
| 1048 private: | |
| 1049 Interval range_; | |
| 1050 }; | |
| 1051 | |
| 1013 class DeferredIncrementRegister: public DeferredAction { | 1052 class DeferredIncrementRegister: public DeferredAction { |
| 1014 public: | 1053 public: |
| 1015 explicit DeferredIncrementRegister(int reg) | 1054 explicit DeferredIncrementRegister(int reg) |
| 1016 : DeferredAction(ActionNode::INCREMENT_REGISTER, reg) { } | 1055 : DeferredAction(ActionNode::INCREMENT_REGISTER, reg) { } |
| 1017 }; | 1056 }; |
| 1018 | 1057 |
| 1019 GenerationVariant() | 1058 GenerationVariant() |
| 1020 : cp_offset_(0), | 1059 : cp_offset_(0), |
| 1021 actions_(NULL), | 1060 actions_(NULL), |
| 1022 backtrack_(NULL), | 1061 backtrack_(NULL), |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1183 Handle<String> pattern, | 1222 Handle<String> pattern, |
| 1184 bool is_ascii); | 1223 bool is_ascii); |
| 1185 | 1224 |
| 1186 static void DotPrint(const char* label, RegExpNode* node, bool ignore_case); | 1225 static void DotPrint(const char* label, RegExpNode* node, bool ignore_case); |
| 1187 }; | 1226 }; |
| 1188 | 1227 |
| 1189 | 1228 |
| 1190 } } // namespace v8::internal | 1229 } } // namespace v8::internal |
| 1191 | 1230 |
| 1192 #endif // V8_JSREGEXP_H_ | 1231 #endif // V8_JSREGEXP_H_ |
| OLD | NEW |