Commit 9b5141ca authored by Iain Ireland's avatar Iain Ireland Committed by Commit Bot

[regexp] Cache min/max-match for RegExpCapture/Group

Unlike the other RegExpTree types, RegExpCapture and RegExpGroup don't
cache their min/maxMatch value. Instead, they compute it by recursing
on the min/maxMatch of the body node. In pathological cases, with
sufficiently small stacks, this can cause stack overflow. (In
SpiderMonkey's case, it was a worker on 32-bit x86.)

It's easy enough to just precompute the value when the body is set.

R=jgruber@chromium.org

Bug: v8:10303
Change-Id: I4ba3d301d9a4a3f3c0cb94966148b747a4092d26
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2090192
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#66673}
parent 73da478c
......@@ -463,7 +463,11 @@ class RegExpQuantifier final : public RegExpTree {
class RegExpCapture final : public RegExpTree {
public:
explicit RegExpCapture(int index)
: body_(nullptr), index_(index), name_(nullptr) {}
: body_(nullptr),
index_(index),
min_match_(0),
max_match_(0),
name_(nullptr) {}
void* Accept(RegExpVisitor* visitor, void* data) override;
RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override;
static RegExpNode* ToNode(RegExpTree* body, int index,
......@@ -473,10 +477,14 @@ 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(); }
int min_match() override { return min_match_; }
int max_match() override { return max_match_; }
RegExpTree* body() { return body_; }
void set_body(RegExpTree* body) { body_ = body; }
void set_body(RegExpTree* body) {
body_ = body;
min_match_ = body->min_match();
max_match_ = body->max_match();
}
int index() const { return index_; }
const ZoneVector<uc16>* name() const { return name_; }
void set_name(const ZoneVector<uc16>* name) { name_ = name; }
......@@ -486,12 +494,17 @@ class RegExpCapture final : public RegExpTree {
private:
RegExpTree* body_;
int index_;
int min_match_;
int max_match_;
const ZoneVector<uc16>* name_;
};
class RegExpGroup final : public RegExpTree {
public:
explicit RegExpGroup(RegExpTree* body) : body_(body) {}
explicit RegExpGroup(RegExpTree* body)
: body_(body),
min_match_(body->min_match()),
max_match_(body->max_match()) {}
void* Accept(RegExpVisitor* visitor, void* data) override;
RegExpNode* ToNode(RegExpCompiler* compiler,
RegExpNode* on_success) override {
......@@ -501,13 +514,15 @@ class RegExpGroup final : public RegExpTree {
bool IsAnchoredAtStart() override { return body_->IsAnchoredAtStart(); }
bool IsAnchoredAtEnd() override { return body_->IsAnchoredAtEnd(); }
bool IsGroup() override;
int min_match() override { return body_->min_match(); }
int max_match() override { return body_->max_match(); }
int min_match() override { return min_match_; }
int max_match() override { return max_match_; }
Interval CaptureRegisters() override { return body_->CaptureRegisters(); }
RegExpTree* body() { return body_; }
private:
RegExpTree* body_;
int min_match_;
int max_match_;
};
class RegExpLookaround final : public RegExpTree {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment