Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(331)

Unified Diff: src/ast/ast.h

Issue 1522353002: [regexp] break recursion in mutually recursive capture/back references. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: lazify min/max match computation Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | src/ast/ast.cc » ('j') | src/ast/ast.cc » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/ast/ast.h
diff --git a/src/ast/ast.h b/src/ast/ast.h
index b4f2992e047215ac95d2c61b96a98d64afbfb5a1..ea81eba4caf9c1c39abf664890178ae84148ae76 100644
--- a/src/ast/ast.h
+++ b/src/ast/ast.h
@@ -2874,6 +2874,7 @@ class RegExpVisitor BASE_EMBEDDED {
class RegExpTree : public ZoneObject {
public:
static const int kInfinity = kMaxInt;
+ static const int kUninitialized = -1;
virtual ~RegExpTree() {}
virtual void* Accept(RegExpVisitor* visitor, void* data) = 0;
virtual RegExpNode* ToNode(RegExpCompiler* compiler,
@@ -2898,7 +2899,12 @@ class RegExpTree : public ZoneObject {
class RegExpDisjunction final : public RegExpTree {
public:
- explicit RegExpDisjunction(ZoneList<RegExpTree*>* alternatives);
+ explicit RegExpDisjunction(ZoneList<RegExpTree*>* alternatives)
+ : alternatives_(alternatives),
+ min_match_(kUninitialized),
+ max_match_(kUninitialized) {
+ DCHECK(alternatives->length() > 1);
+ }
void* Accept(RegExpVisitor* visitor, void* data) override;
RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override;
RegExpDisjunction* AsDisjunction() override;
@@ -2906,10 +2912,18 @@ class RegExpDisjunction final : public RegExpTree {
bool IsDisjunction() override;
bool IsAnchoredAtStart() override;
bool IsAnchoredAtEnd() override;
- int min_match() override { return min_match_; }
- int max_match() override { return max_match_; }
+ int min_match() override {
+ if (min_match_ == kUninitialized) LazilyComputeMatchLengths();
+ return min_match_;
+ }
+ int max_match() override {
+ if (max_match_ == kUninitialized) LazilyComputeMatchLengths();
+ return max_match_;
+ }
ZoneList<RegExpTree*>* alternatives() { return alternatives_; }
+
private:
+ void LazilyComputeMatchLengths();
bool SortConsecutiveAtoms(RegExpCompiler* compiler);
void RationalizeConsecutiveAtoms(RegExpCompiler* compiler);
void FixSingleCharacterDisjunctions(RegExpCompiler* compiler);
@@ -2921,7 +2935,10 @@ class RegExpDisjunction final : public RegExpTree {
class RegExpAlternative final : public RegExpTree {
public:
- explicit RegExpAlternative(ZoneList<RegExpTree*>* nodes);
+ explicit RegExpAlternative(ZoneList<RegExpTree*>* nodes)
+ : nodes_(nodes), min_match_(kUninitialized), max_match_(kUninitialized) {
+ DCHECK(nodes->length() > 1);
+ }
void* Accept(RegExpVisitor* visitor, void* data) override;
RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override;
RegExpAlternative* AsAlternative() override;
@@ -2929,10 +2946,18 @@ class RegExpAlternative final : public RegExpTree {
bool IsAlternative() override;
bool IsAnchoredAtStart() override;
bool IsAnchoredAtEnd() override;
- int min_match() override { return min_match_; }
- int max_match() override { return max_match_; }
+ int min_match() override {
+ if (min_match_ == kUninitialized) LazilyComputeMatchLengths();
+ return min_match_;
+ }
+ int max_match() override {
+ if (max_match_ == kUninitialized) LazilyComputeMatchLengths();
+ return max_match_;
+ }
ZoneList<RegExpTree*>* nodes() { return nodes_; }
+
private:
+ void LazilyComputeMatchLengths();
ZoneList<RegExpTree*>* nodes_;
int min_match_;
int max_match_;
@@ -3075,14 +3100,9 @@ class RegExpQuantifier final : public RegExpTree {
: body_(body),
min_(min),
max_(max),
- min_match_(min * body->min_match()),
- quantifier_type_(type) {
- if (max > 0 && body->max_match() > kInfinity / max) {
- max_match_ = kInfinity;
- } else {
- max_match_ = max * body->max_match();
- }
- }
+ min_match_(kUninitialized),
+ max_match_(kUninitialized),
+ quantifier_type_(type) {}
void* Accept(RegExpVisitor* visitor, void* data) override;
RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override;
static RegExpNode* ToNode(int min,
@@ -3095,8 +3115,14 @@ class RegExpQuantifier final : public RegExpTree {
RegExpQuantifier* AsQuantifier() override;
Interval CaptureRegisters() override;
bool IsQuantifier() override;
- int min_match() override { return min_match_; }
- int max_match() override { return max_match_; }
+ int min_match() override {
+ if (min_match_ == kUninitialized) LazilyComputeMatchLengths();
+ return min_match_;
+ }
+ int max_match() override {
+ if (max_match_ == kUninitialized) LazilyComputeMatchLengths();
+ return max_match_;
+ }
int min() { return min_; }
int max() { return max_; }
bool is_possessive() { return quantifier_type_ == POSSESSIVE; }
@@ -3105,6 +3131,7 @@ class RegExpQuantifier final : public RegExpTree {
RegExpTree* body() { return body_; }
private:
+ void LazilyComputeMatchLengths();
RegExpTree* body_;
int min_;
int max_;
@@ -3180,24 +3207,21 @@ class RegExpLookaround final : public RegExpTree {
class RegExpBackReference final : public RegExpTree {
public:
explicit RegExpBackReference(RegExpCapture* capture)
- : capture_(capture) { }
+ : capture_(capture), max_match_(kUninitialized) {}
void* Accept(RegExpVisitor* visitor, void* data) override;
RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override;
RegExpBackReference* AsBackReference() override;
bool IsBackReference() override;
int min_match() override { return 0; }
- // The capture may not be completely parsed yet, if the reference occurs
- // before the capture. 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 max_match() override {
- return capture_->body() ? capture_->max_match() : 0;
- }
+ int max_match() override;
int index() { return capture_->index(); }
RegExpCapture* capture() { return capture_; }
private:
+ static const int kRecursionMarker = -2;
+ STATIC_ASSERT(kRecursionMarker != kUninitialized);
+
RegExpCapture* capture_;
+ int max_match_;
};
« no previous file with comments | « no previous file | src/ast/ast.cc » ('j') | src/ast/ast.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698