Commit 5058c397 authored by Iain Ireland's avatar Iain Ireland Committed by Commit Bot

[regexp] Add syntax_only option to ParseRegExp

To ensure that regexp syntax errors are reported as early errors, SpiderMonkey calls ParseRegExp at parse time to validate that the regexp parses properly. This does not require the allocation of named capture information. We have a project underway to completely eliminate the allocation of GC things at parse time, which will require us to suppress the allocation of named capture information (or else jump through hoops to implement FixedArray as a non-GC thing).

We can work around this in our shim layer -- for example, by setting a flag on the Factory shim that causes us to allocate dummy objects -- but it's much simpler to add an option to ParseRegExp.

(Note: V8 currently does not treat regexp syntax errors as early errors. See https://bugs.chromium.org/p/v8/issues/detail?id=896.)

Bug: v8:10406
Change-Id: Ib5f0613a54509146e00f90cf61bda4bf03b03859
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2207813
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#67995}
parent 782fa8d8
......@@ -1789,34 +1789,54 @@ RegExpTree* RegExpParser::ParseCharacterClass(const RegExpBuilder* builder) {
#undef CHECK_FAILED
bool RegExpParser::ParseRegExp(Isolate* isolate, Zone* zone,
FlatStringReader* input, JSRegExp::Flags flags,
RegExpCompileData* result) {
bool RegExpParser::Parse(RegExpCompileData* result,
const DisallowHeapAllocation&) {
DCHECK(result != nullptr);
RegExpParser parser(input, flags, isolate, zone);
RegExpTree* tree = parser.ParsePattern();
if (parser.failed()) {
RegExpTree* tree = ParsePattern();
if (failed()) {
DCHECK(tree == nullptr);
DCHECK(parser.error_ != RegExpError::kNone);
result->error = parser.error_;
result->error_pos = parser.error_pos_;
DCHECK(error_ != RegExpError::kNone);
result->error = error_;
result->error_pos = error_pos_;
} else {
DCHECK(tree != nullptr);
DCHECK(parser.error_ == RegExpError::kNone);
DCHECK(error_ == RegExpError::kNone);
if (FLAG_trace_regexp_parser) {
StdoutStream os;
tree->Print(os, zone);
tree->Print(os, zone());
os << "\n";
}
result->tree = tree;
int capture_count = parser.captures_started();
result->simple = tree->IsAtom() && parser.simple() && capture_count == 0;
result->contains_anchor = parser.contains_anchor();
result->capture_name_map = parser.CreateCaptureNameMap();
int capture_count = captures_started();
result->simple = tree->IsAtom() && simple() && capture_count == 0;
result->contains_anchor = contains_anchor();
result->capture_count = capture_count;
}
return !parser.failed();
return !failed();
}
bool RegExpParser::ParseRegExp(Isolate* isolate, Zone* zone,
FlatStringReader* input, JSRegExp::Flags flags,
RegExpCompileData* result) {
RegExpParser parser(input, flags, isolate, zone);
bool success;
{
DisallowHeapAllocation no_gc;
success = parser.Parse(result, no_gc);
}
if (success) {
result->capture_name_map = parser.CreateCaptureNameMap();
}
return success;
}
bool RegExpParser::VerifyRegExpSyntax(Isolate* isolate, Zone* zone,
FlatStringReader* input,
JSRegExp::Flags flags,
const DisallowHeapAllocation& no_gc) {
RegExpParser parser(input, flags, isolate, zone);
RegExpCompileData dummy;
return parser.Parse(&dummy, no_gc);
}
RegExpBuilder::RegExpBuilder(Zone* zone, JSRegExp::Flags flags)
......
......@@ -159,6 +159,12 @@ class V8_EXPORT_PRIVATE RegExpParser {
static bool ParseRegExp(Isolate* isolate, Zone* zone, FlatStringReader* input,
JSRegExp::Flags flags, RegExpCompileData* result);
static bool VerifyRegExpSyntax(Isolate* isolate, Zone* zone,
FlatStringReader* input, JSRegExp::Flags flags,
const DisallowHeapAllocation& no_gc);
private:
bool Parse(RegExpCompileData* result, const DisallowHeapAllocation&);
RegExpTree* ParsePattern();
RegExpTree* ParseDisjunction();
......
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