| Index: src/ast.h
|
| diff --git a/src/ast.h b/src/ast.h
|
| index 14f71a6cc28bfb03e95f2f767c97cce90727542d..63568c2265f563e66b7f7821be6b8d188c69d869 100644
|
| --- a/src/ast.h
|
| +++ b/src/ast.h
|
| @@ -119,7 +119,7 @@ class RegExpCharacterClass;
|
| class RegExpCompiler;
|
| class RegExpDisjunction;
|
| class RegExpEmpty;
|
| -class RegExpLookahead;
|
| +class RegExpLookaround;
|
| class RegExpQuantifier;
|
| class RegExpText;
|
|
|
| @@ -2832,7 +2832,11 @@ class RegExpVisitor BASE_EMBEDDED {
|
|
|
| class RegExpTree : public ZoneObject {
|
| public:
|
| + enum ReadDirection { READ_FORWARD, READ_BACKWARD };
|
| +
|
| static const int kInfinity = kMaxInt;
|
| + explicit RegExpTree(ReadDirection read_direction)
|
| + : read_direction_(read_direction) {}
|
| virtual ~RegExpTree() {}
|
| virtual void* Accept(RegExpVisitor* visitor, void* data) = 0;
|
| virtual RegExpNode* ToNode(RegExpCompiler* compiler,
|
| @@ -2852,12 +2856,19 @@ class RegExpTree : public ZoneObject {
|
| virtual bool Is##Name();
|
| FOR_EACH_REG_EXP_TREE_TYPE(MAKE_ASTYPE)
|
| #undef MAKE_ASTYPE
|
| +
|
| + ReadDirection read_direction() const { return read_direction_; }
|
| + bool read_backward() const { return read_direction_ == READ_BACKWARD; }
|
| +
|
| + protected:
|
| + ReadDirection read_direction_;
|
| };
|
|
|
|
|
| class RegExpDisjunction final : public RegExpTree {
|
| public:
|
| - explicit RegExpDisjunction(ZoneList<RegExpTree*>* alternatives);
|
| + RegExpDisjunction(ZoneList<RegExpTree*>* alternatives,
|
| + ReadDirection read_direction);
|
| void* Accept(RegExpVisitor* visitor, void* data) override;
|
| RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override;
|
| RegExpDisjunction* AsDisjunction() override;
|
| @@ -2880,7 +2891,7 @@ class RegExpDisjunction final : public RegExpTree {
|
|
|
| class RegExpAlternative final : public RegExpTree {
|
| public:
|
| - explicit RegExpAlternative(ZoneList<RegExpTree*>* nodes);
|
| + RegExpAlternative(ZoneList<RegExpTree*>* nodes, ReadDirection read_direction);
|
| void* Accept(RegExpVisitor* visitor, void* data) override;
|
| RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override;
|
| RegExpAlternative* AsAlternative() override;
|
| @@ -2908,7 +2919,8 @@ class RegExpAssertion final : public RegExpTree {
|
| BOUNDARY,
|
| NON_BOUNDARY
|
| };
|
| - explicit RegExpAssertion(AssertionType type) : assertion_type_(type) { }
|
| + RegExpAssertion(AssertionType type, ReadDirection read_direction)
|
| + : RegExpTree(read_direction), assertion_type_(type) {}
|
| void* Accept(RegExpVisitor* visitor, void* data) override;
|
| RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override;
|
| RegExpAssertion* AsAssertion() override;
|
| @@ -2948,12 +2960,11 @@ class CharacterSet final BASE_EMBEDDED {
|
|
|
| class RegExpCharacterClass final : public RegExpTree {
|
| public:
|
| - RegExpCharacterClass(ZoneList<CharacterRange>* ranges, bool is_negated)
|
| - : set_(ranges),
|
| - is_negated_(is_negated) { }
|
| - explicit RegExpCharacterClass(uc16 type)
|
| - : set_(type),
|
| - is_negated_(false) { }
|
| + RegExpCharacterClass(ZoneList<CharacterRange>* ranges, bool is_negated,
|
| + ReadDirection read_direction)
|
| + : RegExpTree(read_direction), set_(ranges), is_negated_(is_negated) {}
|
| + RegExpCharacterClass(uc16 type, ReadDirection read_direction)
|
| + : RegExpTree(read_direction), set_(type), is_negated_(false) {}
|
| void* Accept(RegExpVisitor* visitor, void* data) override;
|
| RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override;
|
| RegExpCharacterClass* AsCharacterClass() override;
|
| @@ -2989,7 +3000,8 @@ class RegExpCharacterClass final : public RegExpTree {
|
|
|
| class RegExpAtom final : public RegExpTree {
|
| public:
|
| - explicit RegExpAtom(Vector<const uc16> data) : data_(data) { }
|
| + RegExpAtom(Vector<const uc16> data, ReadDirection read_direction)
|
| + : RegExpTree(read_direction), data_(data) {}
|
| void* Accept(RegExpVisitor* visitor, void* data) override;
|
| RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override;
|
| RegExpAtom* AsAtom() override;
|
| @@ -3007,7 +3019,8 @@ class RegExpAtom final : public RegExpTree {
|
|
|
| class RegExpText final : public RegExpTree {
|
| public:
|
| - explicit RegExpText(Zone* zone) : elements_(2, zone), length_(0) {}
|
| + RegExpText(Zone* zone, ReadDirection read_direction)
|
| + : RegExpTree(read_direction), elements_(2, zone), length_(0) {}
|
| void* Accept(RegExpVisitor* visitor, void* data) override;
|
| RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override;
|
| RegExpText* AsText() override;
|
| @@ -3030,8 +3043,10 @@ class RegExpText final : public RegExpTree {
|
| class RegExpQuantifier final : public RegExpTree {
|
| public:
|
| enum QuantifierType { GREEDY, NON_GREEDY, POSSESSIVE };
|
| - RegExpQuantifier(int min, int max, QuantifierType type, RegExpTree* body)
|
| - : body_(body),
|
| + RegExpQuantifier(int min, int max, QuantifierType type, RegExpTree* body,
|
| + ReadDirection read_direction)
|
| + : RegExpTree(read_direction),
|
| + body_(body),
|
| min_(min),
|
| max_(max),
|
| min_match_(min * body->min_match()),
|
| @@ -3075,8 +3090,8 @@ class RegExpQuantifier final : public RegExpTree {
|
|
|
| class RegExpCapture final : public RegExpTree {
|
| public:
|
| - explicit RegExpCapture(RegExpTree* body, int index)
|
| - : body_(body), index_(index) { }
|
| + explicit RegExpCapture(int index)
|
| + : RegExpTree(READ_FORWARD), body_(NULL), index_(index) {}
|
| void* Accept(RegExpVisitor* visitor, void* data) override;
|
| RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override;
|
| static RegExpNode* ToNode(RegExpTree* body,
|
| @@ -3088,9 +3103,18 @@ class RegExpCapture final : public RegExpTree {
|
| bool IsAnchoredAtEnd() override;
|
| Interval CaptureRegisters() override;
|
| bool IsCapture() override;
|
| - int min_match() override { return body_->min_match(); }
|
| - int max_match() override { return body_->max_match(); }
|
| + // If body_ is not yet set, the capture is back referenced but not parsed yet.
|
| + // In the ordinary case, nothing has been captured yet, so the back reference
|
| + // must have the length 0.
|
| + // If the back reference is inside a lookbehind, effectively making it a
|
| + // forward reference, we return 0 since lookbehinds have a length of 0.
|
| + int min_match() override { return body_ ? body_->min_match() : 0; }
|
| + int max_match() override { return body_ ? body_->max_match() : 0; }
|
| RegExpTree* body() { return body_; }
|
| + void set_body(RegExpTree* body) { body_ = body; }
|
| + void set_read_direction(ReadDirection read_direction) {
|
| + read_direction_ = read_direction;
|
| + }
|
| int index() { return index_; }
|
| static int StartRegister(int index) { return index * 2; }
|
| static int EndRegister(int index) { return index * 2 + 1; }
|
| @@ -3101,22 +3125,21 @@ class RegExpCapture final : public RegExpTree {
|
| };
|
|
|
|
|
| -class RegExpLookahead final : public RegExpTree {
|
| +class RegExpLookaround final : public RegExpTree {
|
| public:
|
| - RegExpLookahead(RegExpTree* body,
|
| - bool is_positive,
|
| - int capture_count,
|
| - int capture_from)
|
| - : body_(body),
|
| + RegExpLookaround(RegExpTree* body, bool is_positive, int capture_count,
|
| + int capture_from, ReadDirection read_direction)
|
| + : RegExpTree(read_direction),
|
| + body_(body),
|
| is_positive_(is_positive),
|
| capture_count_(capture_count),
|
| - capture_from_(capture_from) { }
|
| + capture_from_(capture_from) {}
|
|
|
| void* Accept(RegExpVisitor* visitor, void* data) override;
|
| RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override;
|
| - RegExpLookahead* AsLookahead() override;
|
| + RegExpLookaround* AsLookaround() override;
|
| Interval CaptureRegisters() override;
|
| - bool IsLookahead() override;
|
| + bool IsLookaround() override;
|
| bool IsAnchoredAtStart() override;
|
| int min_match() override { return 0; }
|
| int max_match() override { return 0; }
|
| @@ -3135,8 +3158,8 @@ class RegExpLookahead final : public RegExpTree {
|
|
|
| class RegExpBackReference final : public RegExpTree {
|
| public:
|
| - explicit RegExpBackReference(RegExpCapture* capture)
|
| - : capture_(capture) { }
|
| + RegExpBackReference(RegExpCapture* capture, ReadDirection read_direction)
|
| + : RegExpTree(read_direction), capture_(capture) {}
|
| void* Accept(RegExpVisitor* visitor, void* data) override;
|
| RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override;
|
| RegExpBackReference* AsBackReference() override;
|
| @@ -3152,7 +3175,7 @@ class RegExpBackReference final : public RegExpTree {
|
|
|
| class RegExpEmpty final : public RegExpTree {
|
| public:
|
| - RegExpEmpty() { }
|
| + RegExpEmpty() : RegExpTree(READ_FORWARD) {}
|
| void* Accept(RegExpVisitor* visitor, void* data) override;
|
| RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override;
|
| RegExpEmpty* AsEmpty() override;
|
|
|