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" |
11 #include "src/ast/variables.h" | 11 #include "src/ast/variables.h" |
12 #include "src/bailout-reason.h" | 12 #include "src/bailout-reason.h" |
13 #include "src/base/flags.h" | 13 #include "src/base/flags.h" |
14 #include "src/base/smart-pointers.h" | 14 #include "src/base/smart-pointers.h" |
15 #include "src/factory.h" | 15 #include "src/factory.h" |
16 #include "src/isolate.h" | 16 #include "src/isolate.h" |
17 #include "src/list.h" | 17 #include "src/list.h" |
18 #include "src/parsing/token.h" | 18 #include "src/parsing/token.h" |
19 #include "src/regexp/jsregexp.h" | |
20 #include "src/runtime/runtime.h" | 19 #include "src/runtime/runtime.h" |
21 #include "src/small-pointer-list.h" | 20 #include "src/small-pointer-list.h" |
22 #include "src/types.h" | 21 #include "src/types.h" |
23 #include "src/utils.h" | 22 #include "src/utils.h" |
24 | 23 |
25 namespace v8 { | 24 namespace v8 { |
26 namespace internal { | 25 namespace internal { |
27 | 26 |
28 // The abstract syntax tree is an intermediate, light-weight | 27 // The abstract syntax tree is an intermediate, light-weight |
29 // representation of the parsed JavaScript code suitable for | 28 // representation of the parsed JavaScript code suitable for |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
104 class AstVisitor; | 103 class AstVisitor; |
105 class Declaration; | 104 class Declaration; |
106 class Module; | 105 class Module; |
107 class BreakableStatement; | 106 class BreakableStatement; |
108 class Expression; | 107 class Expression; |
109 class IterationStatement; | 108 class IterationStatement; |
110 class MaterializedLiteral; | 109 class MaterializedLiteral; |
111 class Statement; | 110 class Statement; |
112 class TypeFeedbackOracle; | 111 class TypeFeedbackOracle; |
113 | 112 |
114 class RegExpAlternative; | |
115 class RegExpAssertion; | |
116 class RegExpAtom; | |
117 class RegExpBackReference; | |
118 class RegExpCapture; | |
119 class RegExpCharacterClass; | |
120 class RegExpCompiler; | |
121 class RegExpDisjunction; | |
122 class RegExpEmpty; | |
123 class RegExpLookaround; | |
124 class RegExpQuantifier; | |
125 class RegExpText; | |
126 | |
127 #define DEF_FORWARD_DECLARATION(type) class type; | 113 #define DEF_FORWARD_DECLARATION(type) class type; |
128 AST_NODE_LIST(DEF_FORWARD_DECLARATION) | 114 AST_NODE_LIST(DEF_FORWARD_DECLARATION) |
129 #undef DEF_FORWARD_DECLARATION | 115 #undef DEF_FORWARD_DECLARATION |
130 | 116 |
131 | 117 |
132 // Typedef only introduced to avoid unreadable code. | 118 // Typedef only introduced to avoid unreadable code. |
133 typedef ZoneList<Handle<String>> ZoneStringList; | 119 typedef ZoneList<Handle<String>> ZoneStringList; |
134 typedef ZoneList<Handle<Object>> ZoneObjectList; | 120 typedef ZoneList<Handle<Object>> ZoneObjectList; |
135 | 121 |
136 | 122 |
(...skipping 2773 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2910 | 2896 |
2911 private: | 2897 private: |
2912 EmptyParentheses(Zone* zone, int pos) : Expression(zone, pos) {} | 2898 EmptyParentheses(Zone* zone, int pos) : Expression(zone, pos) {} |
2913 }; | 2899 }; |
2914 | 2900 |
2915 | 2901 |
2916 #undef DECLARE_NODE_TYPE | 2902 #undef DECLARE_NODE_TYPE |
2917 | 2903 |
2918 | 2904 |
2919 // ---------------------------------------------------------------------------- | 2905 // ---------------------------------------------------------------------------- |
2920 // Regular expressions | |
2921 | |
2922 | |
2923 class RegExpVisitor BASE_EMBEDDED { | |
2924 public: | |
2925 virtual ~RegExpVisitor() { } | |
2926 #define MAKE_CASE(Name) \ | |
2927 virtual void* Visit##Name(RegExp##Name*, void* data) = 0; | |
2928 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_CASE) | |
2929 #undef MAKE_CASE | |
2930 }; | |
2931 | |
2932 | |
2933 class RegExpTree : public ZoneObject { | |
2934 public: | |
2935 static const int kInfinity = kMaxInt; | |
2936 virtual ~RegExpTree() {} | |
2937 virtual void* Accept(RegExpVisitor* visitor, void* data) = 0; | |
2938 virtual RegExpNode* ToNode(RegExpCompiler* compiler, | |
2939 RegExpNode* on_success) = 0; | |
2940 virtual bool IsTextElement() { return false; } | |
2941 virtual bool IsAnchoredAtStart() { return false; } | |
2942 virtual bool IsAnchoredAtEnd() { return false; } | |
2943 virtual int min_match() = 0; | |
2944 virtual int max_match() = 0; | |
2945 // Returns the interval of registers used for captures within this | |
2946 // expression. | |
2947 virtual Interval CaptureRegisters() { return Interval::Empty(); } | |
2948 virtual void AppendToText(RegExpText* text, Zone* zone); | |
2949 std::ostream& Print(std::ostream& os, Zone* zone); // NOLINT | |
2950 #define MAKE_ASTYPE(Name) \ | |
2951 virtual RegExp##Name* As##Name(); \ | |
2952 virtual bool Is##Name(); | |
2953 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_ASTYPE) | |
2954 #undef MAKE_ASTYPE | |
2955 }; | |
2956 | |
2957 | |
2958 class RegExpDisjunction final : public RegExpTree { | |
2959 public: | |
2960 explicit RegExpDisjunction(ZoneList<RegExpTree*>* alternatives); | |
2961 void* Accept(RegExpVisitor* visitor, void* data) override; | |
2962 RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override; | |
2963 RegExpDisjunction* AsDisjunction() override; | |
2964 Interval CaptureRegisters() override; | |
2965 bool IsDisjunction() override; | |
2966 bool IsAnchoredAtStart() override; | |
2967 bool IsAnchoredAtEnd() override; | |
2968 int min_match() override { return min_match_; } | |
2969 int max_match() override { return max_match_; } | |
2970 ZoneList<RegExpTree*>* alternatives() { return alternatives_; } | |
2971 private: | |
2972 bool SortConsecutiveAtoms(RegExpCompiler* compiler); | |
2973 void RationalizeConsecutiveAtoms(RegExpCompiler* compiler); | |
2974 void FixSingleCharacterDisjunctions(RegExpCompiler* compiler); | |
2975 ZoneList<RegExpTree*>* alternatives_; | |
2976 int min_match_; | |
2977 int max_match_; | |
2978 }; | |
2979 | |
2980 | |
2981 class RegExpAlternative final : public RegExpTree { | |
2982 public: | |
2983 explicit RegExpAlternative(ZoneList<RegExpTree*>* nodes); | |
2984 void* Accept(RegExpVisitor* visitor, void* data) override; | |
2985 RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override; | |
2986 RegExpAlternative* AsAlternative() override; | |
2987 Interval CaptureRegisters() override; | |
2988 bool IsAlternative() override; | |
2989 bool IsAnchoredAtStart() override; | |
2990 bool IsAnchoredAtEnd() override; | |
2991 int min_match() override { return min_match_; } | |
2992 int max_match() override { return max_match_; } | |
2993 ZoneList<RegExpTree*>* nodes() { return nodes_; } | |
2994 private: | |
2995 ZoneList<RegExpTree*>* nodes_; | |
2996 int min_match_; | |
2997 int max_match_; | |
2998 }; | |
2999 | |
3000 | |
3001 class RegExpAssertion final : public RegExpTree { | |
3002 public: | |
3003 enum AssertionType { | |
3004 START_OF_LINE, | |
3005 START_OF_INPUT, | |
3006 END_OF_LINE, | |
3007 END_OF_INPUT, | |
3008 BOUNDARY, | |
3009 NON_BOUNDARY | |
3010 }; | |
3011 explicit RegExpAssertion(AssertionType type) : assertion_type_(type) { } | |
3012 void* Accept(RegExpVisitor* visitor, void* data) override; | |
3013 RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override; | |
3014 RegExpAssertion* AsAssertion() override; | |
3015 bool IsAssertion() override; | |
3016 bool IsAnchoredAtStart() override; | |
3017 bool IsAnchoredAtEnd() override; | |
3018 int min_match() override { return 0; } | |
3019 int max_match() override { return 0; } | |
3020 AssertionType assertion_type() { return assertion_type_; } | |
3021 private: | |
3022 AssertionType assertion_type_; | |
3023 }; | |
3024 | |
3025 | |
3026 class CharacterSet final BASE_EMBEDDED { | |
3027 public: | |
3028 explicit CharacterSet(uc16 standard_set_type) | |
3029 : ranges_(NULL), | |
3030 standard_set_type_(standard_set_type) {} | |
3031 explicit CharacterSet(ZoneList<CharacterRange>* ranges) | |
3032 : ranges_(ranges), | |
3033 standard_set_type_(0) {} | |
3034 ZoneList<CharacterRange>* ranges(Zone* zone); | |
3035 uc16 standard_set_type() { return standard_set_type_; } | |
3036 void set_standard_set_type(uc16 special_set_type) { | |
3037 standard_set_type_ = special_set_type; | |
3038 } | |
3039 bool is_standard() { return standard_set_type_ != 0; } | |
3040 void Canonicalize(); | |
3041 private: | |
3042 ZoneList<CharacterRange>* ranges_; | |
3043 // If non-zero, the value represents a standard set (e.g., all whitespace | |
3044 // characters) without having to expand the ranges. | |
3045 uc16 standard_set_type_; | |
3046 }; | |
3047 | |
3048 | |
3049 class RegExpCharacterClass final : public RegExpTree { | |
3050 public: | |
3051 RegExpCharacterClass(ZoneList<CharacterRange>* ranges, bool is_negated) | |
3052 : set_(ranges), | |
3053 is_negated_(is_negated) { } | |
3054 explicit RegExpCharacterClass(uc16 type) | |
3055 : set_(type), | |
3056 is_negated_(false) { } | |
3057 void* Accept(RegExpVisitor* visitor, void* data) override; | |
3058 RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override; | |
3059 RegExpCharacterClass* AsCharacterClass() override; | |
3060 bool IsCharacterClass() override; | |
3061 bool IsTextElement() override { return true; } | |
3062 int min_match() override { return 1; } | |
3063 int max_match() override { return 1; } | |
3064 void AppendToText(RegExpText* text, Zone* zone) override; | |
3065 CharacterSet character_set() { return set_; } | |
3066 // TODO(lrn): Remove need for complex version if is_standard that | |
3067 // recognizes a mangled standard set and just do { return set_.is_special(); } | |
3068 bool is_standard(Zone* zone); | |
3069 // Returns a value representing the standard character set if is_standard() | |
3070 // returns true. | |
3071 // Currently used values are: | |
3072 // s : unicode whitespace | |
3073 // S : unicode non-whitespace | |
3074 // w : ASCII word character (digit, letter, underscore) | |
3075 // W : non-ASCII word character | |
3076 // d : ASCII digit | |
3077 // D : non-ASCII digit | |
3078 // . : non-unicode non-newline | |
3079 // * : All characters | |
3080 uc16 standard_type() { return set_.standard_set_type(); } | |
3081 ZoneList<CharacterRange>* ranges(Zone* zone) { return set_.ranges(zone); } | |
3082 bool is_negated() { return is_negated_; } | |
3083 | |
3084 private: | |
3085 CharacterSet set_; | |
3086 bool is_negated_; | |
3087 }; | |
3088 | |
3089 | |
3090 class RegExpAtom final : public RegExpTree { | |
3091 public: | |
3092 explicit RegExpAtom(Vector<const uc16> data) : data_(data) { } | |
3093 void* Accept(RegExpVisitor* visitor, void* data) override; | |
3094 RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override; | |
3095 RegExpAtom* AsAtom() override; | |
3096 bool IsAtom() override; | |
3097 bool IsTextElement() override { return true; } | |
3098 int min_match() override { return data_.length(); } | |
3099 int max_match() override { return data_.length(); } | |
3100 void AppendToText(RegExpText* text, Zone* zone) override; | |
3101 Vector<const uc16> data() { return data_; } | |
3102 int length() { return data_.length(); } | |
3103 private: | |
3104 Vector<const uc16> data_; | |
3105 }; | |
3106 | |
3107 | |
3108 class RegExpText final : public RegExpTree { | |
3109 public: | |
3110 explicit RegExpText(Zone* zone) : elements_(2, zone), length_(0) {} | |
3111 void* Accept(RegExpVisitor* visitor, void* data) override; | |
3112 RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override; | |
3113 RegExpText* AsText() override; | |
3114 bool IsText() override; | |
3115 bool IsTextElement() override { return true; } | |
3116 int min_match() override { return length_; } | |
3117 int max_match() override { return length_; } | |
3118 void AppendToText(RegExpText* text, Zone* zone) override; | |
3119 void AddElement(TextElement elm, Zone* zone) { | |
3120 elements_.Add(elm, zone); | |
3121 length_ += elm.length(); | |
3122 } | |
3123 ZoneList<TextElement>* elements() { return &elements_; } | |
3124 private: | |
3125 ZoneList<TextElement> elements_; | |
3126 int length_; | |
3127 }; | |
3128 | |
3129 | |
3130 class RegExpQuantifier final : public RegExpTree { | |
3131 public: | |
3132 enum QuantifierType { GREEDY, NON_GREEDY, POSSESSIVE }; | |
3133 RegExpQuantifier(int min, int max, QuantifierType type, RegExpTree* body) | |
3134 : body_(body), | |
3135 min_(min), | |
3136 max_(max), | |
3137 min_match_(min * body->min_match()), | |
3138 quantifier_type_(type) { | |
3139 if (max > 0 && body->max_match() > kInfinity / max) { | |
3140 max_match_ = kInfinity; | |
3141 } else { | |
3142 max_match_ = max * body->max_match(); | |
3143 } | |
3144 } | |
3145 void* Accept(RegExpVisitor* visitor, void* data) override; | |
3146 RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override; | |
3147 static RegExpNode* ToNode(int min, | |
3148 int max, | |
3149 bool is_greedy, | |
3150 RegExpTree* body, | |
3151 RegExpCompiler* compiler, | |
3152 RegExpNode* on_success, | |
3153 bool not_at_start = false); | |
3154 RegExpQuantifier* AsQuantifier() override; | |
3155 Interval CaptureRegisters() override; | |
3156 bool IsQuantifier() override; | |
3157 int min_match() override { return min_match_; } | |
3158 int max_match() override { return max_match_; } | |
3159 int min() { return min_; } | |
3160 int max() { return max_; } | |
3161 bool is_possessive() { return quantifier_type_ == POSSESSIVE; } | |
3162 bool is_non_greedy() { return quantifier_type_ == NON_GREEDY; } | |
3163 bool is_greedy() { return quantifier_type_ == GREEDY; } | |
3164 RegExpTree* body() { return body_; } | |
3165 | |
3166 private: | |
3167 RegExpTree* body_; | |
3168 int min_; | |
3169 int max_; | |
3170 int min_match_; | |
3171 int max_match_; | |
3172 QuantifierType quantifier_type_; | |
3173 }; | |
3174 | |
3175 | |
3176 class RegExpCapture final : public RegExpTree { | |
3177 public: | |
3178 explicit RegExpCapture(int index) : body_(NULL), index_(index) {} | |
3179 void* Accept(RegExpVisitor* visitor, void* data) override; | |
3180 RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override; | |
3181 static RegExpNode* ToNode(RegExpTree* body, | |
3182 int index, | |
3183 RegExpCompiler* compiler, | |
3184 RegExpNode* on_success); | |
3185 RegExpCapture* AsCapture() override; | |
3186 bool IsAnchoredAtStart() override; | |
3187 bool IsAnchoredAtEnd() override; | |
3188 Interval CaptureRegisters() override; | |
3189 bool IsCapture() override; | |
3190 int min_match() override { return body_->min_match(); } | |
3191 int max_match() override { return body_->max_match(); } | |
3192 RegExpTree* body() { return body_; } | |
3193 void set_body(RegExpTree* body) { body_ = body; } | |
3194 int index() { return index_; } | |
3195 static int StartRegister(int index) { return index * 2; } | |
3196 static int EndRegister(int index) { return index * 2 + 1; } | |
3197 | |
3198 private: | |
3199 RegExpTree* body_; | |
3200 int index_; | |
3201 }; | |
3202 | |
3203 | |
3204 class RegExpLookaround final : public RegExpTree { | |
3205 public: | |
3206 enum Type { LOOKAHEAD, LOOKBEHIND }; | |
3207 | |
3208 RegExpLookaround(RegExpTree* body, bool is_positive, int capture_count, | |
3209 int capture_from, Type type) | |
3210 : body_(body), | |
3211 is_positive_(is_positive), | |
3212 capture_count_(capture_count), | |
3213 capture_from_(capture_from), | |
3214 type_(type) {} | |
3215 | |
3216 void* Accept(RegExpVisitor* visitor, void* data) override; | |
3217 RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override; | |
3218 RegExpLookaround* AsLookaround() override; | |
3219 Interval CaptureRegisters() override; | |
3220 bool IsLookaround() override; | |
3221 bool IsAnchoredAtStart() override; | |
3222 int min_match() override { return 0; } | |
3223 int max_match() override { return 0; } | |
3224 RegExpTree* body() { return body_; } | |
3225 bool is_positive() { return is_positive_; } | |
3226 int capture_count() { return capture_count_; } | |
3227 int capture_from() { return capture_from_; } | |
3228 Type type() { return type_; } | |
3229 | |
3230 private: | |
3231 RegExpTree* body_; | |
3232 bool is_positive_; | |
3233 int capture_count_; | |
3234 int capture_from_; | |
3235 Type type_; | |
3236 }; | |
3237 | |
3238 | |
3239 class RegExpBackReference final : public RegExpTree { | |
3240 public: | |
3241 explicit RegExpBackReference(RegExpCapture* capture) | |
3242 : capture_(capture) { } | |
3243 void* Accept(RegExpVisitor* visitor, void* data) override; | |
3244 RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override; | |
3245 RegExpBackReference* AsBackReference() override; | |
3246 bool IsBackReference() override; | |
3247 int min_match() override { return 0; } | |
3248 // The back reference may be recursive, e.g. /(\2)(\1)/. To avoid infinite | |
3249 // recursion, we give up. Ignorance is bliss. | |
3250 int max_match() override { return kInfinity; } | |
3251 int index() { return capture_->index(); } | |
3252 RegExpCapture* capture() { return capture_; } | |
3253 private: | |
3254 RegExpCapture* capture_; | |
3255 }; | |
3256 | |
3257 | |
3258 class RegExpEmpty final : public RegExpTree { | |
3259 public: | |
3260 RegExpEmpty() { } | |
3261 void* Accept(RegExpVisitor* visitor, void* data) override; | |
3262 RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override; | |
3263 RegExpEmpty* AsEmpty() override; | |
3264 bool IsEmpty() override; | |
3265 int min_match() override { return 0; } | |
3266 int max_match() override { return 0; } | |
3267 }; | |
3268 | |
3269 | |
3270 // ---------------------------------------------------------------------------- | |
3271 // Basic visitor | 2906 // Basic visitor |
3272 // - leaf node visitors are abstract. | 2907 // - leaf node visitors are abstract. |
3273 | 2908 |
3274 class AstVisitor BASE_EMBEDDED { | 2909 class AstVisitor BASE_EMBEDDED { |
3275 public: | 2910 public: |
3276 AstVisitor() {} | 2911 AstVisitor() {} |
3277 virtual ~AstVisitor() {} | 2912 virtual ~AstVisitor() {} |
3278 | 2913 |
3279 // Stack overflow check and dynamic dispatch. | 2914 // Stack overflow check and dynamic dispatch. |
3280 virtual void Visit(AstNode* node) = 0; | 2915 virtual void Visit(AstNode* node) = 0; |
(...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3769 // the parser-level zone. | 3404 // the parser-level zone. |
3770 Zone* parser_zone_; | 3405 Zone* parser_zone_; |
3771 AstValueFactory* ast_value_factory_; | 3406 AstValueFactory* ast_value_factory_; |
3772 }; | 3407 }; |
3773 | 3408 |
3774 | 3409 |
3775 } // namespace internal | 3410 } // namespace internal |
3776 } // namespace v8 | 3411 } // namespace v8 |
3777 | 3412 |
3778 #endif // V8_AST_AST_H_ | 3413 #endif // V8_AST_AST_H_ |
OLD | NEW |