Chromium Code Reviews| Index: src/ast/ast.cc |
| diff --git a/src/ast/ast.cc b/src/ast/ast.cc |
| index 3c8eb1ff7f1c109e4e9ee83824bc551815d2f55b..d140a40407b3da105d62d9cfe5d20e7c78068591 100644 |
| --- a/src/ast/ast.cc |
| +++ b/src/ast/ast.cc |
| @@ -926,6 +926,31 @@ bool RegExpCapture::IsAnchoredAtEnd() { |
| } |
| +int RegExpBackReference::max_match() { |
| + switch (max_match_) { |
| + case kRecursionMarker: |
| + // The back reference references a capture that references this back |
| + // reference, leading to a recursion, e.g. /(\2)(\1)/. |
| + // Such captures cannot be satisfied and have the length 0. |
|
erikcorry
2015/12/15 09:45:43
This may well just be a bug in a comment, but here
Yang
2015/12/15 09:52:18
You are right. It should be "Such back references
erikcorry
2015/12/15 10:18:18
My example regexp seems to contradict the revised
|
| + max_match_ = 0; |
| + break; |
| + case kUninitialized: |
| + // The max match length of a back reference is the length of the capture. |
| + // Mark this back reference to break possible recursion before |
| + // descending into the capture. |
| + max_match_ = kRecursionMarker; |
| + // The capture has been parsed. |
| + DCHECK_NOT_NULL(capture_->body()); |
| + max_match_ = capture_->max_match(); |
| + break; |
| + default: |
| + // max_match_ has already been found. |
| + break; |
| + } |
| + return max_match_; |
| +} |
| + |
| + |
| // Convert regular expression trees to a simple sexp representation. |
| // This representation should be different from the input grammar |
| // in as many cases as possible, to make it more difficult for incorrect |
| @@ -1091,14 +1116,14 @@ std::ostream& RegExpTree::Print(std::ostream& os, Zone* zone) { // NOLINT |
| } |
| -RegExpDisjunction::RegExpDisjunction(ZoneList<RegExpTree*>* alternatives) |
| - : alternatives_(alternatives) { |
| - DCHECK(alternatives->length() > 1); |
| - RegExpTree* first_alternative = alternatives->at(0); |
| +void RegExpDisjunction::LazilyComputeMatchLengths() { |
| + // We cannot compute this in the constructor because at the time of parsing |
| + // back referenced captures have not yet been parsed yet. |
| + RegExpTree* first_alternative = alternatives_->at(0); |
| min_match_ = first_alternative->min_match(); |
|
erikcorry
2015/12/15 09:45:43
This looks a bit dodgy. We are not done calculati
Yang
2015/12/15 09:52:18
I think this is fine. We can only have a recursion
|
| max_match_ = first_alternative->max_match(); |
| - for (int i = 1; i < alternatives->length(); i++) { |
| - RegExpTree* alternative = alternatives->at(i); |
| + for (int i = 1; i < alternatives_->length(); i++) { |
| + RegExpTree* alternative = alternatives_->at(i); |
| min_match_ = Min(min_match_, alternative->min_match()); |
| max_match_ = Max(max_match_, alternative->max_match()); |
| } |
| @@ -1113,13 +1138,14 @@ static int IncreaseBy(int previous, int increase) { |
| } |
| } |
| -RegExpAlternative::RegExpAlternative(ZoneList<RegExpTree*>* nodes) |
| - : nodes_(nodes) { |
| - DCHECK(nodes->length() > 1); |
| + |
| +void RegExpAlternative::LazilyComputeMatchLengths() { |
| + // We cannot compute this in the constructor because at the time of parsing |
| + // back referenced captures have not yet been parsed yet. |
| min_match_ = 0; |
| max_match_ = 0; |
| - for (int i = 0; i < nodes->length(); i++) { |
| - RegExpTree* node = nodes->at(i); |
| + for (int i = 0; i < nodes_->length(); i++) { |
| + RegExpTree* node = nodes_->at(i); |
| int node_min_match = node->min_match(); |
| min_match_ = IncreaseBy(min_match_, node_min_match); |
| int node_max_match = node->max_match(); |
| @@ -1128,6 +1154,18 @@ RegExpAlternative::RegExpAlternative(ZoneList<RegExpTree*>* nodes) |
| } |
| +void RegExpQuantifier::LazilyComputeMatchLengths() { |
| + // We cannot compute this in the constructor because at the time of parsing |
| + // back referenced captures have not yet been parsed yet. |
| + min_match_ = min_ * body_->min_match(); |
| + if (max_ > 0 && body_->max_match() > kInfinity / max_) { |
| + max_match_ = kInfinity; |
| + } else { |
| + max_match_ = max_ * body_->max_match(); |
| + } |
| +} |
| + |
| + |
| CaseClause::CaseClause(Zone* zone, Expression* label, |
| ZoneList<Statement*>* statements, int pos) |
| : Expression(zone, pos), |