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_AST_AST_H_ | 5 #ifndef V8_AST_AST_H_ |
6 #define V8_AST_AST_H_ | 6 #define V8_AST_AST_H_ |
7 | 7 |
8 #include "src/assembler.h" | 8 #include "src/assembler.h" |
9 #include "src/ast/ast-value-factory.h" | 9 #include "src/ast/ast-value-factory.h" |
10 #include "src/ast/modules.h" | 10 #include "src/ast/modules.h" |
(...skipping 2856 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2867 #define MAKE_CASE(Name) \ | 2867 #define MAKE_CASE(Name) \ |
2868 virtual void* Visit##Name(RegExp##Name*, void* data) = 0; | 2868 virtual void* Visit##Name(RegExp##Name*, void* data) = 0; |
2869 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_CASE) | 2869 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_CASE) |
2870 #undef MAKE_CASE | 2870 #undef MAKE_CASE |
2871 }; | 2871 }; |
2872 | 2872 |
2873 | 2873 |
2874 class RegExpTree : public ZoneObject { | 2874 class RegExpTree : public ZoneObject { |
2875 public: | 2875 public: |
2876 static const int kInfinity = kMaxInt; | 2876 static const int kInfinity = kMaxInt; |
| 2877 static const int kUninitialized = -1; |
2877 virtual ~RegExpTree() {} | 2878 virtual ~RegExpTree() {} |
2878 virtual void* Accept(RegExpVisitor* visitor, void* data) = 0; | 2879 virtual void* Accept(RegExpVisitor* visitor, void* data) = 0; |
2879 virtual RegExpNode* ToNode(RegExpCompiler* compiler, | 2880 virtual RegExpNode* ToNode(RegExpCompiler* compiler, |
2880 RegExpNode* on_success) = 0; | 2881 RegExpNode* on_success) = 0; |
2881 virtual bool IsTextElement() { return false; } | 2882 virtual bool IsTextElement() { return false; } |
2882 virtual bool IsAnchoredAtStart() { return false; } | 2883 virtual bool IsAnchoredAtStart() { return false; } |
2883 virtual bool IsAnchoredAtEnd() { return false; } | 2884 virtual bool IsAnchoredAtEnd() { return false; } |
2884 virtual int min_match() = 0; | 2885 virtual int min_match() = 0; |
2885 virtual int max_match() = 0; | 2886 virtual int max_match() = 0; |
2886 // Returns the interval of registers used for captures within this | 2887 // Returns the interval of registers used for captures within this |
2887 // expression. | 2888 // expression. |
2888 virtual Interval CaptureRegisters() { return Interval::Empty(); } | 2889 virtual Interval CaptureRegisters() { return Interval::Empty(); } |
2889 virtual void AppendToText(RegExpText* text, Zone* zone); | 2890 virtual void AppendToText(RegExpText* text, Zone* zone); |
2890 std::ostream& Print(std::ostream& os, Zone* zone); // NOLINT | 2891 std::ostream& Print(std::ostream& os, Zone* zone); // NOLINT |
2891 #define MAKE_ASTYPE(Name) \ | 2892 #define MAKE_ASTYPE(Name) \ |
2892 virtual RegExp##Name* As##Name(); \ | 2893 virtual RegExp##Name* As##Name(); \ |
2893 virtual bool Is##Name(); | 2894 virtual bool Is##Name(); |
2894 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_ASTYPE) | 2895 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_ASTYPE) |
2895 #undef MAKE_ASTYPE | 2896 #undef MAKE_ASTYPE |
2896 }; | 2897 }; |
2897 | 2898 |
2898 | 2899 |
2899 class RegExpDisjunction final : public RegExpTree { | 2900 class RegExpDisjunction final : public RegExpTree { |
2900 public: | 2901 public: |
2901 explicit RegExpDisjunction(ZoneList<RegExpTree*>* alternatives); | 2902 explicit RegExpDisjunction(ZoneList<RegExpTree*>* alternatives) |
| 2903 : alternatives_(alternatives), |
| 2904 min_match_(kUninitialized), |
| 2905 max_match_(kUninitialized) { |
| 2906 DCHECK(alternatives->length() > 1); |
| 2907 } |
2902 void* Accept(RegExpVisitor* visitor, void* data) override; | 2908 void* Accept(RegExpVisitor* visitor, void* data) override; |
2903 RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override; | 2909 RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override; |
2904 RegExpDisjunction* AsDisjunction() override; | 2910 RegExpDisjunction* AsDisjunction() override; |
2905 Interval CaptureRegisters() override; | 2911 Interval CaptureRegisters() override; |
2906 bool IsDisjunction() override; | 2912 bool IsDisjunction() override; |
2907 bool IsAnchoredAtStart() override; | 2913 bool IsAnchoredAtStart() override; |
2908 bool IsAnchoredAtEnd() override; | 2914 bool IsAnchoredAtEnd() override; |
2909 int min_match() override { return min_match_; } | 2915 int min_match() override { |
2910 int max_match() override { return max_match_; } | 2916 if (min_match_ == kUninitialized) LazilyComputeMatchLengths(); |
| 2917 return min_match_; |
| 2918 } |
| 2919 int max_match() override { |
| 2920 if (max_match_ == kUninitialized) LazilyComputeMatchLengths(); |
| 2921 return max_match_; |
| 2922 } |
2911 ZoneList<RegExpTree*>* alternatives() { return alternatives_; } | 2923 ZoneList<RegExpTree*>* alternatives() { return alternatives_; } |
| 2924 |
2912 private: | 2925 private: |
| 2926 void LazilyComputeMatchLengths(); |
2913 bool SortConsecutiveAtoms(RegExpCompiler* compiler); | 2927 bool SortConsecutiveAtoms(RegExpCompiler* compiler); |
2914 void RationalizeConsecutiveAtoms(RegExpCompiler* compiler); | 2928 void RationalizeConsecutiveAtoms(RegExpCompiler* compiler); |
2915 void FixSingleCharacterDisjunctions(RegExpCompiler* compiler); | 2929 void FixSingleCharacterDisjunctions(RegExpCompiler* compiler); |
2916 ZoneList<RegExpTree*>* alternatives_; | 2930 ZoneList<RegExpTree*>* alternatives_; |
2917 int min_match_; | 2931 int min_match_; |
2918 int max_match_; | 2932 int max_match_; |
2919 }; | 2933 }; |
2920 | 2934 |
2921 | 2935 |
2922 class RegExpAlternative final : public RegExpTree { | 2936 class RegExpAlternative final : public RegExpTree { |
2923 public: | 2937 public: |
2924 explicit RegExpAlternative(ZoneList<RegExpTree*>* nodes); | 2938 explicit RegExpAlternative(ZoneList<RegExpTree*>* nodes) |
| 2939 : nodes_(nodes), min_match_(kUninitialized), max_match_(kUninitialized) { |
| 2940 DCHECK(nodes->length() > 1); |
| 2941 } |
2925 void* Accept(RegExpVisitor* visitor, void* data) override; | 2942 void* Accept(RegExpVisitor* visitor, void* data) override; |
2926 RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override; | 2943 RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override; |
2927 RegExpAlternative* AsAlternative() override; | 2944 RegExpAlternative* AsAlternative() override; |
2928 Interval CaptureRegisters() override; | 2945 Interval CaptureRegisters() override; |
2929 bool IsAlternative() override; | 2946 bool IsAlternative() override; |
2930 bool IsAnchoredAtStart() override; | 2947 bool IsAnchoredAtStart() override; |
2931 bool IsAnchoredAtEnd() override; | 2948 bool IsAnchoredAtEnd() override; |
2932 int min_match() override { return min_match_; } | 2949 int min_match() override { |
2933 int max_match() override { return max_match_; } | 2950 if (min_match_ == kUninitialized) LazilyComputeMatchLengths(); |
| 2951 return min_match_; |
| 2952 } |
| 2953 int max_match() override { |
| 2954 if (max_match_ == kUninitialized) LazilyComputeMatchLengths(); |
| 2955 return max_match_; |
| 2956 } |
2934 ZoneList<RegExpTree*>* nodes() { return nodes_; } | 2957 ZoneList<RegExpTree*>* nodes() { return nodes_; } |
| 2958 |
2935 private: | 2959 private: |
| 2960 void LazilyComputeMatchLengths(); |
2936 ZoneList<RegExpTree*>* nodes_; | 2961 ZoneList<RegExpTree*>* nodes_; |
2937 int min_match_; | 2962 int min_match_; |
2938 int max_match_; | 2963 int max_match_; |
2939 }; | 2964 }; |
2940 | 2965 |
2941 | 2966 |
2942 class RegExpAssertion final : public RegExpTree { | 2967 class RegExpAssertion final : public RegExpTree { |
2943 public: | 2968 public: |
2944 enum AssertionType { | 2969 enum AssertionType { |
2945 START_OF_LINE, | 2970 START_OF_LINE, |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3068 }; | 3093 }; |
3069 | 3094 |
3070 | 3095 |
3071 class RegExpQuantifier final : public RegExpTree { | 3096 class RegExpQuantifier final : public RegExpTree { |
3072 public: | 3097 public: |
3073 enum QuantifierType { GREEDY, NON_GREEDY, POSSESSIVE }; | 3098 enum QuantifierType { GREEDY, NON_GREEDY, POSSESSIVE }; |
3074 RegExpQuantifier(int min, int max, QuantifierType type, RegExpTree* body) | 3099 RegExpQuantifier(int min, int max, QuantifierType type, RegExpTree* body) |
3075 : body_(body), | 3100 : body_(body), |
3076 min_(min), | 3101 min_(min), |
3077 max_(max), | 3102 max_(max), |
3078 min_match_(min * body->min_match()), | 3103 min_match_(kUninitialized), |
3079 quantifier_type_(type) { | 3104 max_match_(kUninitialized), |
3080 if (max > 0 && body->max_match() > kInfinity / max) { | 3105 quantifier_type_(type) {} |
3081 max_match_ = kInfinity; | |
3082 } else { | |
3083 max_match_ = max * body->max_match(); | |
3084 } | |
3085 } | |
3086 void* Accept(RegExpVisitor* visitor, void* data) override; | 3106 void* Accept(RegExpVisitor* visitor, void* data) override; |
3087 RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override; | 3107 RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override; |
3088 static RegExpNode* ToNode(int min, | 3108 static RegExpNode* ToNode(int min, |
3089 int max, | 3109 int max, |
3090 bool is_greedy, | 3110 bool is_greedy, |
3091 RegExpTree* body, | 3111 RegExpTree* body, |
3092 RegExpCompiler* compiler, | 3112 RegExpCompiler* compiler, |
3093 RegExpNode* on_success, | 3113 RegExpNode* on_success, |
3094 bool not_at_start = false); | 3114 bool not_at_start = false); |
3095 RegExpQuantifier* AsQuantifier() override; | 3115 RegExpQuantifier* AsQuantifier() override; |
3096 Interval CaptureRegisters() override; | 3116 Interval CaptureRegisters() override; |
3097 bool IsQuantifier() override; | 3117 bool IsQuantifier() override; |
3098 int min_match() override { return min_match_; } | 3118 int min_match() override { |
3099 int max_match() override { return max_match_; } | 3119 if (min_match_ == kUninitialized) LazilyComputeMatchLengths(); |
| 3120 return min_match_; |
| 3121 } |
| 3122 int max_match() override { |
| 3123 if (max_match_ == kUninitialized) LazilyComputeMatchLengths(); |
| 3124 return max_match_; |
| 3125 } |
3100 int min() { return min_; } | 3126 int min() { return min_; } |
3101 int max() { return max_; } | 3127 int max() { return max_; } |
3102 bool is_possessive() { return quantifier_type_ == POSSESSIVE; } | 3128 bool is_possessive() { return quantifier_type_ == POSSESSIVE; } |
3103 bool is_non_greedy() { return quantifier_type_ == NON_GREEDY; } | 3129 bool is_non_greedy() { return quantifier_type_ == NON_GREEDY; } |
3104 bool is_greedy() { return quantifier_type_ == GREEDY; } | 3130 bool is_greedy() { return quantifier_type_ == GREEDY; } |
3105 RegExpTree* body() { return body_; } | 3131 RegExpTree* body() { return body_; } |
3106 | 3132 |
3107 private: | 3133 private: |
| 3134 void LazilyComputeMatchLengths(); |
3108 RegExpTree* body_; | 3135 RegExpTree* body_; |
3109 int min_; | 3136 int min_; |
3110 int max_; | 3137 int max_; |
3111 int min_match_; | 3138 int min_match_; |
3112 int max_match_; | 3139 int max_match_; |
3113 QuantifierType quantifier_type_; | 3140 QuantifierType quantifier_type_; |
3114 }; | 3141 }; |
3115 | 3142 |
3116 | 3143 |
3117 class RegExpCapture final : public RegExpTree { | 3144 class RegExpCapture final : public RegExpTree { |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3173 bool is_positive_; | 3200 bool is_positive_; |
3174 int capture_count_; | 3201 int capture_count_; |
3175 int capture_from_; | 3202 int capture_from_; |
3176 Type type_; | 3203 Type type_; |
3177 }; | 3204 }; |
3178 | 3205 |
3179 | 3206 |
3180 class RegExpBackReference final : public RegExpTree { | 3207 class RegExpBackReference final : public RegExpTree { |
3181 public: | 3208 public: |
3182 explicit RegExpBackReference(RegExpCapture* capture) | 3209 explicit RegExpBackReference(RegExpCapture* capture) |
3183 : capture_(capture) { } | 3210 : capture_(capture), max_match_(kUninitialized) {} |
3184 void* Accept(RegExpVisitor* visitor, void* data) override; | 3211 void* Accept(RegExpVisitor* visitor, void* data) override; |
3185 RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override; | 3212 RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override; |
3186 RegExpBackReference* AsBackReference() override; | 3213 RegExpBackReference* AsBackReference() override; |
3187 bool IsBackReference() override; | 3214 bool IsBackReference() override; |
3188 int min_match() override { return 0; } | 3215 int min_match() override { return 0; } |
3189 // The capture may not be completely parsed yet, if the reference occurs | 3216 int max_match() override; |
3190 // before the capture. In the ordinary case, nothing has been captured yet, | |
3191 // so the back reference must have the length 0. If the back reference is | |
3192 // inside a lookbehind, effectively making it a forward reference, we return | |
3193 // 0 since lookbehinds have a length of 0. | |
3194 int max_match() override { | |
3195 return capture_->body() ? capture_->max_match() : 0; | |
3196 } | |
3197 int index() { return capture_->index(); } | 3217 int index() { return capture_->index(); } |
3198 RegExpCapture* capture() { return capture_; } | 3218 RegExpCapture* capture() { return capture_; } |
3199 private: | 3219 private: |
| 3220 static const int kRecursionMarker = -2; |
| 3221 STATIC_ASSERT(kRecursionMarker != kUninitialized); |
| 3222 |
3200 RegExpCapture* capture_; | 3223 RegExpCapture* capture_; |
| 3224 int max_match_; |
3201 }; | 3225 }; |
3202 | 3226 |
3203 | 3227 |
3204 class RegExpEmpty final : public RegExpTree { | 3228 class RegExpEmpty final : public RegExpTree { |
3205 public: | 3229 public: |
3206 RegExpEmpty() { } | 3230 RegExpEmpty() { } |
3207 void* Accept(RegExpVisitor* visitor, void* data) override; | 3231 void* Accept(RegExpVisitor* visitor, void* data) override; |
3208 RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override; | 3232 RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override; |
3209 RegExpEmpty* AsEmpty() override; | 3233 RegExpEmpty* AsEmpty() override; |
3210 bool IsEmpty() override; | 3234 bool IsEmpty() override; |
(...skipping 504 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3715 // the parser-level zone. | 3739 // the parser-level zone. |
3716 Zone* parser_zone_; | 3740 Zone* parser_zone_; |
3717 AstValueFactory* ast_value_factory_; | 3741 AstValueFactory* ast_value_factory_; |
3718 }; | 3742 }; |
3719 | 3743 |
3720 | 3744 |
3721 } // namespace internal | 3745 } // namespace internal |
3722 } // namespace v8 | 3746 } // namespace v8 |
3723 | 3747 |
3724 #endif // V8_AST_AST_H_ | 3748 #endif // V8_AST_AST_H_ |
OLD | NEW |