LCOV - code coverage report
Current view: top level - src/regexp - regexp-ast.h (source / functions) Hit Total Coverage
Test: app.info Lines: 83 98 84.7 %
Date: 2017-04-26 Functions: 37 66 56.1 %

          Line data    Source code
       1             : // Copyright 2016 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #ifndef V8_REGEXP_REGEXP_AST_H_
       6             : #define V8_REGEXP_REGEXP_AST_H_
       7             : 
       8             : #include "src/objects.h"
       9             : #include "src/utils.h"
      10             : #include "src/zone/zone-containers.h"
      11             : #include "src/zone/zone.h"
      12             : 
      13             : namespace v8 {
      14             : namespace internal {
      15             : 
      16             : #define FOR_EACH_REG_EXP_TREE_TYPE(VISIT) \
      17             :   VISIT(Disjunction)                      \
      18             :   VISIT(Alternative)                      \
      19             :   VISIT(Assertion)                        \
      20             :   VISIT(CharacterClass)                   \
      21             :   VISIT(Atom)                             \
      22             :   VISIT(Quantifier)                       \
      23             :   VISIT(Capture)                          \
      24             :   VISIT(Group)                            \
      25             :   VISIT(Lookaround)                       \
      26             :   VISIT(BackReference)                    \
      27             :   VISIT(Empty)                            \
      28             :   VISIT(Text)
      29             : 
      30             : #define FORWARD_DECLARE(Name) class RegExp##Name;
      31             : FOR_EACH_REG_EXP_TREE_TYPE(FORWARD_DECLARE)
      32             : #undef FORWARD_DECLARE
      33             : 
      34             : class RegExpCompiler;
      35             : class RegExpNode;
      36             : class RegExpTree;
      37             : 
      38             : 
      39        2114 : class RegExpVisitor BASE_EMBEDDED {
      40             :  public:
      41           0 :   virtual ~RegExpVisitor() {}
      42             : #define MAKE_CASE(Name) \
      43             :   virtual void* Visit##Name(RegExp##Name*, void* data) = 0;
      44             :   FOR_EACH_REG_EXP_TREE_TYPE(MAKE_CASE)
      45             : #undef MAKE_CASE
      46             : };
      47             : 
      48             : 
      49             : // A simple closed interval.
      50             : class Interval {
      51             :  public:
      52             :   Interval() : from_(kNone), to_(kNone) {}
      53      272129 :   Interval(int from, int to) : from_(from), to_(to) {}
      54             :   Interval Union(Interval that) {
      55       48649 :     if (that.from_ == kNone)
      56             :       return *this;
      57        5495 :     else if (from_ == kNone)
      58             :       return that;
      59             :     else
      60             :       return Interval(Min(from_, that.from_), Max(to_, that.to_));
      61             :   }
      62       76942 :   bool Contains(int value) { return (from_ <= value) && (value <= to_); }
      63             :   bool is_empty() { return from_ == kNone; }
      64             :   int from() const { return from_; }
      65             :   int to() const { return to_; }
      66             :   static Interval Empty() { return Interval(); }
      67             :   static const int kNone = -1;
      68             : 
      69             :  private:
      70             :   int from_;
      71             :   int to_;
      72             : };
      73             : 
      74             : 
      75             : // Represents code units in the range from from_ to to_, both ends are
      76             : // inclusive.
      77             : class CharacterRange {
      78             :  public:
      79             :   CharacterRange() : from_(0), to_(0) {}
      80             :   // For compatibility with the CHECK_OK macro
      81             :   CharacterRange(void* null) { DCHECK_NULL(null); }  // NOLINT
      82             :   static void AddClassEscape(uc16 type, ZoneList<CharacterRange>* ranges,
      83             :                              Zone* zone);
      84             :   // Add class escapes. Add case equivalent closure for \w and \W if necessary.
      85             :   static void AddClassEscape(uc16 type, ZoneList<CharacterRange>* ranges,
      86             :                              bool add_unicode_case_equivalents, Zone* zone);
      87             :   static Vector<const int> GetWordBounds();
      88             :   static inline CharacterRange Singleton(uc32 value) {
      89             :     return CharacterRange(value, value);
      90             :   }
      91             :   static inline CharacterRange Range(uc32 from, uc32 to) {
      92             :     DCHECK(0 <= from && to <= String::kMaxCodePoint);
      93             :     DCHECK(static_cast<uint32_t>(from) <= static_cast<uint32_t>(to));
      94             :     return CharacterRange(from, to);
      95             :   }
      96             :   static inline CharacterRange Everything() {
      97             :     return CharacterRange(0, String::kMaxCodePoint);
      98             :   }
      99       60787 :   static inline ZoneList<CharacterRange>* List(Zone* zone,
     100             :                                                CharacterRange range) {
     101             :     ZoneList<CharacterRange>* list =
     102       60787 :         new (zone) ZoneList<CharacterRange>(1, zone);
     103             :     list->Add(range, zone);
     104       60787 :     return list;
     105             :   }
     106       24893 :   bool Contains(uc32 i) { return from_ <= i && i <= to_; }
     107             :   uc32 from() const { return from_; }
     108             :   void set_from(uc32 value) { from_ = value; }
     109             :   uc32 to() const { return to_; }
     110             :   void set_to(uc32 value) { to_ = value; }
     111             :   bool is_valid() { return from_ <= to_; }
     112      297971 :   bool IsEverything(uc16 max) { return from_ == 0 && to_ >= max; }
     113             :   bool IsSingleton() { return (from_ == to_); }
     114             :   static void AddCaseEquivalents(Isolate* isolate, Zone* zone,
     115             :                                  ZoneList<CharacterRange>* ranges,
     116             :                                  bool is_one_byte);
     117             :   // Whether a range list is in canonical form: Ranges ordered by from value,
     118             :   // and ranges non-overlapping and non-adjacent.
     119             :   static bool IsCanonical(ZoneList<CharacterRange>* ranges);
     120             :   // Convert range list to canonical form. The characters covered by the ranges
     121             :   // will still be the same, but no character is in more than one range, and
     122             :   // adjacent ranges are merged. The resulting list may be shorter than the
     123             :   // original, but cannot be longer.
     124             :   static void Canonicalize(ZoneList<CharacterRange>* ranges);
     125             :   // Negate the contents of a character range in canonical form.
     126             :   static void Negate(ZoneList<CharacterRange>* src,
     127             :                      ZoneList<CharacterRange>* dst, Zone* zone);
     128             :   static const int kStartMarker = (1 << 24);
     129             :   static const int kPayloadMask = (1 << 24) - 1;
     130             : 
     131             :  private:
     132             :   CharacterRange(uc32 from, uc32 to) : from_(from), to_(to) {}
     133             : 
     134             :   uc32 from_;
     135             :   uc32 to_;
     136             : };
     137             : 
     138             : 
     139             : class CharacterSet final BASE_EMBEDDED {
     140             :  public:
     141             :   explicit CharacterSet(uc16 standard_set_type)
     142       88395 :       : ranges_(NULL), standard_set_type_(standard_set_type) {}
     143             :   explicit CharacterSet(ZoneList<CharacterRange>* ranges)
     144      292465 :       : ranges_(ranges), standard_set_type_(0) {}
     145             :   ZoneList<CharacterRange>* ranges(Zone* zone);
     146             :   uc16 standard_set_type() { return standard_set_type_; }
     147             :   void set_standard_set_type(uc16 special_set_type) {
     148       16583 :     standard_set_type_ = special_set_type;
     149             :   }
     150             :   bool is_standard() { return standard_set_type_ != 0; }
     151             :   void Canonicalize();
     152             : 
     153             :  private:
     154             :   ZoneList<CharacterRange>* ranges_;
     155             :   // If non-zero, the value represents a standard set (e.g., all whitespace
     156             :   // characters) without having to expand the ranges.
     157             :   uc16 standard_set_type_;
     158             : };
     159             : 
     160             : 
     161             : class TextElement final BASE_EMBEDDED {
     162             :  public:
     163             :   enum TextType { ATOM, CHAR_CLASS };
     164             : 
     165             :   static TextElement Atom(RegExpAtom* atom);
     166             :   static TextElement CharClass(RegExpCharacterClass* char_class);
     167             : 
     168             :   int cp_offset() const { return cp_offset_; }
     169      391123 :   void set_cp_offset(int cp_offset) { cp_offset_ = cp_offset; }
     170             :   int length() const;
     171             : 
     172             :   TextType text_type() const { return text_type_; }
     173             : 
     174             :   RegExpTree* tree() const { return tree_; }
     175             : 
     176     8627839 :   RegExpAtom* atom() const {
     177             :     DCHECK(text_type() == ATOM);
     178             :     return reinterpret_cast<RegExpAtom*>(tree());
     179             :   }
     180             : 
     181             :   RegExpCharacterClass* char_class() const {
     182             :     DCHECK(text_type() == CHAR_CLASS);
     183             :     return reinterpret_cast<RegExpCharacterClass*>(tree());
     184             :   }
     185             : 
     186             :  private:
     187             :   TextElement(TextType text_type, RegExpTree* tree)
     188             :       : cp_offset_(-1), text_type_(text_type), tree_(tree) {}
     189             : 
     190             :   int cp_offset_;
     191             :   TextType text_type_;
     192             :   RegExpTree* tree_;
     193             : };
     194             : 
     195             : 
     196     7731696 : class RegExpTree : public ZoneObject {
     197             :  public:
     198             :   static const int kInfinity = kMaxInt;
     199           0 :   virtual ~RegExpTree() {}
     200             :   virtual void* Accept(RegExpVisitor* visitor, void* data) = 0;
     201             :   virtual RegExpNode* ToNode(RegExpCompiler* compiler,
     202             :                              RegExpNode* on_success) = 0;
     203     1690281 :   virtual bool IsTextElement() { return false; }
     204       88744 :   virtual bool IsAnchoredAtStart() { return false; }
     205       89490 :   virtual bool IsAnchoredAtEnd() { return false; }
     206             :   virtual int min_match() = 0;
     207             :   virtual int max_match() = 0;
     208             :   // Returns the interval of registers used for captures within this
     209             :   // expression.
     210     1657715 :   virtual Interval CaptureRegisters() { return Interval::Empty(); }
     211             :   virtual void AppendToText(RegExpText* text, Zone* zone);
     212             :   std::ostream& Print(std::ostream& os, Zone* zone);  // NOLINT
     213             : #define MAKE_ASTYPE(Name)           \
     214             :   virtual RegExp##Name* As##Name(); \
     215             :   virtual bool Is##Name();
     216             :   FOR_EACH_REG_EXP_TREE_TYPE(MAKE_ASTYPE)
     217             : #undef MAKE_ASTYPE
     218             : };
     219             : 
     220             : 
     221           0 : class RegExpDisjunction final : public RegExpTree {
     222             :  public:
     223             :   explicit RegExpDisjunction(ZoneList<RegExpTree*>* alternatives);
     224             :   void* Accept(RegExpVisitor* visitor, void* data) override;
     225             :   RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override;
     226             :   RegExpDisjunction* AsDisjunction() override;
     227             :   Interval CaptureRegisters() override;
     228             :   bool IsDisjunction() override;
     229             :   bool IsAnchoredAtStart() override;
     230             :   bool IsAnchoredAtEnd() override;
     231       32051 :   int min_match() override { return min_match_; }
     232       35443 :   int max_match() override { return max_match_; }
     233             :   ZoneList<RegExpTree*>* alternatives() { return alternatives_; }
     234             : 
     235             :  private:
     236             :   bool SortConsecutiveAtoms(RegExpCompiler* compiler);
     237             :   void RationalizeConsecutiveAtoms(RegExpCompiler* compiler);
     238             :   void FixSingleCharacterDisjunctions(RegExpCompiler* compiler);
     239             :   ZoneList<RegExpTree*>* alternatives_;
     240             :   int min_match_;
     241             :   int max_match_;
     242             : };
     243             : 
     244             : 
     245           0 : class RegExpAlternative final : public RegExpTree {
     246             :  public:
     247             :   explicit RegExpAlternative(ZoneList<RegExpTree*>* nodes);
     248             :   void* Accept(RegExpVisitor* visitor, void* data) override;
     249             :   RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override;
     250             :   RegExpAlternative* AsAlternative() override;
     251             :   Interval CaptureRegisters() override;
     252             :   bool IsAlternative() override;
     253             :   bool IsAnchoredAtStart() override;
     254             :   bool IsAnchoredAtEnd() override;
     255       47909 :   int min_match() override { return min_match_; }
     256       78375 :   int max_match() override { return max_match_; }
     257             :   ZoneList<RegExpTree*>* nodes() { return nodes_; }
     258             : 
     259             :  private:
     260             :   ZoneList<RegExpTree*>* nodes_;
     261             :   int min_match_;
     262             :   int max_match_;
     263             : };
     264             : 
     265             : 
     266           0 : class RegExpAssertion final : public RegExpTree {
     267             :  public:
     268             :   enum AssertionType {
     269             :     START_OF_LINE,
     270             :     START_OF_INPUT,
     271             :     END_OF_LINE,
     272             :     END_OF_INPUT,
     273             :     BOUNDARY,
     274             :     NON_BOUNDARY
     275             :   };
     276       25111 :   explicit RegExpAssertion(AssertionType type) : assertion_type_(type) {}
     277             :   void* Accept(RegExpVisitor* visitor, void* data) override;
     278             :   RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override;
     279             :   RegExpAssertion* AsAssertion() override;
     280             :   bool IsAssertion() override;
     281             :   bool IsAnchoredAtStart() override;
     282             :   bool IsAnchoredAtEnd() override;
     283       24735 :   int min_match() override { return 0; }
     284       25789 :   int max_match() override { return 0; }
     285             :   AssertionType assertion_type() { return assertion_type_; }
     286             : 
     287             :  private:
     288             :   AssertionType assertion_type_;
     289             : };
     290             : 
     291             : 
     292           0 : class RegExpCharacterClass final : public RegExpTree {
     293             :  public:
     294             :   // NEGATED: The character class is negated and should match everything but
     295             :   //     the specified ranges.
     296             :   // CONTAINS_SPLIT_SURROGATE: The character class contains part of a split
     297             :   //     surrogate and should not be unicode-desugared (crbug.com/641091).
     298             :   enum Flag {
     299             :     NEGATED = 1 << 0,
     300             :     CONTAINS_SPLIT_SURROGATE = 1 << 1,
     301             :   };
     302             :   typedef base::Flags<Flag> Flags;
     303             : 
     304             :   explicit RegExpCharacterClass(ZoneList<CharacterRange>* ranges,
     305             :                                 Flags flags = Flags())
     306      584930 :       : set_(ranges), flags_(flags) {}
     307       88395 :   explicit RegExpCharacterClass(uc16 type) : set_(type), flags_(0) {}
     308             :   void* Accept(RegExpVisitor* visitor, void* data) override;
     309             :   RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override;
     310             :   RegExpCharacterClass* AsCharacterClass() override;
     311             :   bool IsCharacterClass() override;
     312      219689 :   bool IsTextElement() override { return true; }
     313      279787 :   int min_match() override { return 1; }
     314             :   // The character class may match two code units for unicode regexps.
     315             :   // TODO(yangguo): we should split this class for usage in TextElement, and
     316             :   //                make max_match() dependent on the character class content.
     317      153220 :   int max_match() override { return 2; }
     318             :   void AppendToText(RegExpText* text, Zone* zone) override;
     319             :   CharacterSet character_set() { return set_; }
     320             :   // TODO(lrn): Remove need for complex version if is_standard that
     321             :   // recognizes a mangled standard set and just do { return set_.is_special(); }
     322             :   bool is_standard(Zone* zone);
     323             :   // Returns a value representing the standard character set if is_standard()
     324             :   // returns true.
     325             :   // Currently used values are:
     326             :   // s : unicode whitespace
     327             :   // S : unicode non-whitespace
     328             :   // w : ASCII word character (digit, letter, underscore)
     329             :   // W : non-ASCII word character
     330             :   // d : ASCII digit
     331             :   // D : non-ASCII digit
     332             :   // . : non-newline
     333             :   // * : All characters, for advancing unanchored regexp
     334       23859 :   uc16 standard_type() { return set_.standard_set_type(); }
     335      941221 :   ZoneList<CharacterRange>* ranges(Zone* zone) { return set_.ranges(zone); }
     336             :   bool is_negated() const { return (flags_ & NEGATED) != 0; }
     337             :   bool contains_split_surrogate() const {
     338             :     return (flags_ & CONTAINS_SPLIT_SURROGATE) != 0;
     339             :   }
     340             : 
     341             :  private:
     342             :   CharacterSet set_;
     343             :   const Flags flags_;
     344             : };
     345             : 
     346             : 
     347           0 : class RegExpAtom final : public RegExpTree {
     348             :  public:
     349     2758251 :   explicit RegExpAtom(Vector<const uc16> data) : data_(data) {}
     350             :   void* Accept(RegExpVisitor* visitor, void* data) override;
     351             :   RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override;
     352             :   RegExpAtom* AsAtom() override;
     353             :   bool IsAtom() override;
     354         593 :   bool IsTextElement() override { return true; }
     355     5512937 :   int min_match() override { return data_.length(); }
     356     4742658 :   int max_match() override { return data_.length(); }
     357             :   void AppendToText(RegExpText* text, Zone* zone) override;
     358             :   Vector<const uc16> data() { return data_; }
     359     9072374 :   int length() { return data_.length(); }
     360             : 
     361             :  private:
     362             :   Vector<const uc16> data_;
     363             : };
     364             : 
     365             : 
     366           0 : class RegExpText final : public RegExpTree {
     367             :  public:
     368        5990 :   explicit RegExpText(Zone* zone) : elements_(2, zone), length_(0) {}
     369             :   void* Accept(RegExpVisitor* visitor, void* data) override;
     370             :   RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override;
     371             :   RegExpText* AsText() override;
     372             :   bool IsText() override;
     373           0 :   bool IsTextElement() override { return true; }
     374        3705 :   int min_match() override { return length_; }
     375        5728 :   int max_match() override { return length_; }
     376             :   void AppendToText(RegExpText* text, Zone* zone) override;
     377       20323 :   void AddElement(TextElement elm, Zone* zone) {
     378             :     elements_.Add(elm, zone);
     379       20323 :     length_ += elm.length();
     380       20323 :   }
     381             :   ZoneList<TextElement>* elements() { return &elements_; }
     382             : 
     383             :  private:
     384             :   ZoneList<TextElement> elements_;
     385             :   int length_;
     386             : };
     387             : 
     388             : 
     389           0 : class RegExpQuantifier final : public RegExpTree {
     390             :  public:
     391             :   enum QuantifierType { GREEDY, NON_GREEDY, POSSESSIVE };
     392     2300978 :   RegExpQuantifier(int min, int max, QuantifierType type, RegExpTree* body)
     393             :       : body_(body),
     394             :         min_(min),
     395             :         max_(max),
     396     2300978 :         min_match_(min * body->min_match()),
     397     4601956 :         quantifier_type_(type) {
     398     2300978 :     if (max > 0 && body->max_match() > kInfinity / max) {
     399       46906 :       max_match_ = kInfinity;
     400             :     } else {
     401     2254072 :       max_match_ = max * body->max_match();
     402             :     }
     403     2300978 :   }
     404             :   void* Accept(RegExpVisitor* visitor, void* data) override;
     405             :   RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override;
     406             :   static RegExpNode* ToNode(int min, int max, bool is_greedy, RegExpTree* body,
     407             :                             RegExpCompiler* compiler, RegExpNode* on_success,
     408             :                             bool not_at_start = false);
     409             :   RegExpQuantifier* AsQuantifier() override;
     410             :   Interval CaptureRegisters() override;
     411             :   bool IsQuantifier() override;
     412     2296749 :   int min_match() override { return min_match_; }
     413     2302966 :   int max_match() override { return max_match_; }
     414             :   int min() { return min_; }
     415             :   int max() { return max_; }
     416             :   bool is_possessive() { return quantifier_type_ == POSSESSIVE; }
     417             :   bool is_non_greedy() { return quantifier_type_ == NON_GREEDY; }
     418     1540393 :   bool is_greedy() { return quantifier_type_ == GREEDY; }
     419             :   RegExpTree* body() { return body_; }
     420             : 
     421             :  private:
     422             :   RegExpTree* body_;
     423             :   int min_;
     424             :   int max_;
     425             :   int min_match_;
     426             :   int max_match_;
     427             :   QuantifierType quantifier_type_;
     428             : };
     429             : 
     430             : 
     431           0 : class RegExpCapture final : public RegExpTree {
     432             :  public:
     433             :   explicit RegExpCapture(int index)
     434     1644385 :       : body_(NULL), index_(index), name_(nullptr) {}
     435             :   void* Accept(RegExpVisitor* visitor, void* data) override;
     436             :   RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override;
     437             :   static RegExpNode* ToNode(RegExpTree* body, int index,
     438             :                             RegExpCompiler* compiler, RegExpNode* on_success);
     439             :   RegExpCapture* AsCapture() override;
     440             :   bool IsAnchoredAtStart() override;
     441             :   bool IsAnchoredAtEnd() override;
     442             :   Interval CaptureRegisters() override;
     443             :   bool IsCapture() override;
     444       88105 :   int min_match() override { return body_->min_match(); }
     445      108677 :   int max_match() override { return body_->max_match(); }
     446             :   RegExpTree* body() { return body_; }
     447     1644385 :   void set_body(RegExpTree* body) { body_ = body; }
     448             :   int index() { return index_; }
     449             :   const ZoneVector<uc16>* name() const { return name_; }
     450        1658 :   void set_name(const ZoneVector<uc16>* name) { name_ = name; }
     451      138326 :   static int StartRegister(int index) { return index * 2; }
     452      145580 :   static int EndRegister(int index) { return index * 2 + 1; }
     453             : 
     454             :  private:
     455             :   RegExpTree* body_;
     456             :   int index_;
     457             :   const ZoneVector<uc16>* name_;
     458             : };
     459             : 
     460           0 : class RegExpGroup final : public RegExpTree {
     461             :  public:
     462       34923 :   explicit RegExpGroup(RegExpTree* body) : body_(body) {}
     463             :   void* Accept(RegExpVisitor* visitor, void* data) override;
     464       13196 :   RegExpNode* ToNode(RegExpCompiler* compiler,
     465             :                      RegExpNode* on_success) override {
     466       13196 :     return body_->ToNode(compiler, on_success);
     467             :   }
     468             :   RegExpGroup* AsGroup() override;
     469         311 :   bool IsAnchoredAtStart() override { return body_->IsAnchoredAtStart(); }
     470         299 :   bool IsAnchoredAtEnd() override { return body_->IsAnchoredAtEnd(); }
     471             :   bool IsGroup() override;
     472       39443 :   int min_match() override { return body_->min_match(); }
     473       49956 :   int max_match() override { return body_->max_match(); }
     474       16723 :   Interval CaptureRegisters() override { return body_->CaptureRegisters(); }
     475             :   RegExpTree* body() { return body_; }
     476             : 
     477             :  private:
     478             :   RegExpTree* body_;
     479             : };
     480             : 
     481           0 : class RegExpLookaround final : public RegExpTree {
     482             :  public:
     483             :   enum Type { LOOKAHEAD, LOOKBEHIND };
     484             : 
     485             :   RegExpLookaround(RegExpTree* body, bool is_positive, int capture_count,
     486             :                    int capture_from, Type type)
     487             :       : body_(body),
     488             :         is_positive_(is_positive),
     489             :         capture_count_(capture_count),
     490             :         capture_from_(capture_from),
     491        4471 :         type_(type) {}
     492             : 
     493             :   void* Accept(RegExpVisitor* visitor, void* data) override;
     494             :   RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override;
     495             :   RegExpLookaround* AsLookaround() override;
     496             :   Interval CaptureRegisters() override;
     497             :   bool IsLookaround() override;
     498             :   bool IsAnchoredAtStart() override;
     499        4000 :   int min_match() override { return 0; }
     500        5688 :   int max_match() override { return 0; }
     501             :   RegExpTree* body() { return body_; }
     502             :   bool is_positive() { return is_positive_; }
     503             :   int capture_count() { return capture_count_; }
     504             :   int capture_from() { return capture_from_; }
     505             :   Type type() { return type_; }
     506             : 
     507             :   class Builder {
     508             :    public:
     509             :     Builder(bool is_positive, RegExpNode* on_success,
     510             :             int stack_pointer_register, int position_register,
     511             :             int capture_register_count = 0, int capture_register_start = 0);
     512             :     RegExpNode* on_match_success() { return on_match_success_; }
     513             :     RegExpNode* ForMatch(RegExpNode* match);
     514             : 
     515             :    private:
     516             :     bool is_positive_;
     517             :     RegExpNode* on_match_success_;
     518             :     RegExpNode* on_success_;
     519             :     int stack_pointer_register_;
     520             :     int position_register_;
     521             :   };
     522             : 
     523             :  private:
     524             :   RegExpTree* body_;
     525             :   bool is_positive_;
     526             :   int capture_count_;
     527             :   int capture_from_;
     528             :   Type type_;
     529             : };
     530             : 
     531             : 
     532           0 : class RegExpBackReference final : public RegExpTree {
     533             :  public:
     534         432 :   RegExpBackReference() : capture_(nullptr), name_(nullptr) {}
     535             :   explicit RegExpBackReference(RegExpCapture* capture)
     536        6070 :       : capture_(capture), name_(nullptr) {}
     537             :   void* Accept(RegExpVisitor* visitor, void* data) override;
     538             :   RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override;
     539             :   RegExpBackReference* AsBackReference() override;
     540             :   bool IsBackReference() override;
     541        6437 :   int min_match() override { return 0; }
     542             :   // The back reference may be recursive, e.g. /(\2)(\1)/. To avoid infinite
     543             :   // recursion, we give up. Ignorance is bliss.
     544        8922 :   int max_match() override { return kInfinity; }
     545        3510 :   int index() { return capture_->index(); }
     546             :   RegExpCapture* capture() { return capture_; }
     547         278 :   void set_capture(RegExpCapture* capture) { capture_ = capture; }
     548             :   const ZoneVector<uc16>* name() const { return name_; }
     549         432 :   void set_name(const ZoneVector<uc16>* name) { name_ = name; }
     550             : 
     551             :  private:
     552             :   RegExpCapture* capture_;
     553             :   const ZoneVector<uc16>* name_;
     554             : };
     555             : 
     556             : 
     557           0 : class RegExpEmpty final : public RegExpTree {
     558             :  public:
     559      461862 :   RegExpEmpty() {}
     560             :   void* Accept(RegExpVisitor* visitor, void* data) override;
     561             :   RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override;
     562             :   RegExpEmpty* AsEmpty() override;
     563             :   bool IsEmpty() override;
     564        2377 :   int min_match() override { return 0; }
     565        2684 :   int max_match() override { return 0; }
     566             : };
     567             : 
     568             : }  // namespace internal
     569             : }  // namespace v8
     570             : 
     571             : #endif  // V8_REGEXP_REGEXP_AST_H_

Generated by: LCOV version 1.10