Commit 66a85b8e authored by Jakob Gruber's avatar Jakob Gruber Committed by V8 LUCI CQ

[regexp] Replace JSRegExp::Flags uses by RegExpFlags

.. and decrease the include-ball size.

Change-Id: Id35358a6882156f6684475b7f0b0193f8ca5eaf5
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3103313
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarPatrick Thier <pthier@chromium.org>
Cr-Commit-Position: refs/heads/main@{#76386}
parent 1e6628e8
......@@ -391,7 +391,9 @@ MaybeHandle<JSRegExp> JSRegExp::Initialize(Handle<JSRegExp> regexp,
source = String::Flatten(isolate, source);
RETURN_ON_EXCEPTION(
isolate, RegExp::Compile(isolate, regexp, source, flags, backtrack_limit),
isolate,
RegExp::Compile(isolate, regexp, source, JSRegExp::AsRegExpFlags(flags),
backtrack_limit),
JSRegExp);
Handle<String> escaped_source;
......
......@@ -16,12 +16,14 @@ namespace {
// TODO(mbid, v8:10765): Currently the experimental engine doesn't support
// UTF-16, but this shouldn't be too hard to implement.
constexpr base::uc32 kMaxSupportedCodepoint = 0xFFFFu;
#ifdef DEBUG
constexpr base::uc32 kMaxCodePoint = 0x10ffff;
#endif // DEBUG
class CanBeHandledVisitor final : private RegExpVisitor {
// Visitor to implement `ExperimentalRegExp::CanBeHandled`.
public:
static bool Check(RegExpTree* tree, JSRegExp::Flags flags,
int capture_count) {
static bool Check(RegExpTree* tree, RegExpFlags flags, int capture_count) {
if (!AreSuitableFlags(flags)) return false;
CanBeHandledVisitor visitor;
tree->Accept(&visitor, nullptr);
......@@ -31,15 +33,15 @@ class CanBeHandledVisitor final : private RegExpVisitor {
private:
CanBeHandledVisitor() = default;
static bool AreSuitableFlags(JSRegExp::Flags flags) {
static bool AreSuitableFlags(RegExpFlags flags) {
// TODO(mbid, v8:10765): We should be able to support all flags in the
// future.
static constexpr JSRegExp::Flags kAllowedFlags =
JSRegExp::kGlobal | JSRegExp::kSticky | JSRegExp::kMultiline |
JSRegExp::kDotAll | JSRegExp::kLinear;
static constexpr RegExpFlags kAllowedFlags =
RegExpFlag::kGlobal | RegExpFlag::kSticky | RegExpFlag::kMultiline |
RegExpFlag::kDotAll | RegExpFlag::kLinear;
// We support Unicode iff kUnicode is among the supported flags.
STATIC_ASSERT(ExperimentalRegExp::kSupportsUnicode ==
((kAllowedFlags & JSRegExp::kUnicode) != 0));
IsUnicode(kAllowedFlags));
return (flags & ~kAllowedFlags) == 0;
}
......@@ -173,7 +175,7 @@ class CanBeHandledVisitor final : private RegExpVisitor {
} // namespace
bool ExperimentalRegExpCompiler::CanBeHandled(RegExpTree* tree,
JSRegExp::Flags flags,
RegExpFlags flags,
int capture_count) {
return CanBeHandledVisitor::Check(tree, flags, capture_count);
}
......@@ -294,11 +296,10 @@ class BytecodeAssembler {
class CompileVisitor : private RegExpVisitor {
public:
static ZoneList<RegExpInstruction> Compile(RegExpTree* tree,
JSRegExp::Flags flags,
Zone* zone) {
RegExpFlags flags, Zone* zone) {
CompileVisitor compiler(zone);
if ((flags & JSRegExp::kSticky) == 0 && !tree->IsAnchoredAtStart()) {
if (!IsSticky(flags) && !tree->IsAnchoredAtStart()) {
// The match is not anchored, i.e. may start at any input position, so we
// emit a preamble corresponding to /.*?/. This skips an arbitrary
// prefix in the input non-greedily.
......@@ -409,7 +410,7 @@ class CompileVisitor : private RegExpVisitor {
base::uc16 from_uc16 = static_cast<base::uc16>(from);
base::uc32 to = (*ranges)[i].to();
DCHECK_IMPLIES(to > kMaxSupportedCodepoint, to == String::kMaxCodePoint);
DCHECK_IMPLIES(to > kMaxSupportedCodepoint, to == kMaxCodePoint);
base::uc16 to_uc16 =
static_cast<base::uc16>(std::min(to, kMaxSupportedCodepoint));
......@@ -627,7 +628,7 @@ class CompileVisitor : private RegExpVisitor {
} // namespace
ZoneList<RegExpInstruction> ExperimentalRegExpCompiler::Compile(
RegExpTree* tree, JSRegExp::Flags flags, Zone* zone) {
RegExpTree* tree, RegExpFlags flags, Zone* zone) {
return CompileVisitor::Compile(tree, flags, zone);
}
......
......@@ -7,6 +7,7 @@
#include "src/regexp/experimental/experimental-bytecode.h"
#include "src/regexp/regexp-ast.h"
#include "src/regexp/regexp-flags.h"
#include "src/zone/zone-list.h"
namespace v8 {
......@@ -19,13 +20,13 @@ class ExperimentalRegExpCompiler final : public AllStatic {
// but see the definition.
// TODO(mbid,v8:10765): Currently more things are not handled, e.g. some
// quantifiers and unicode.
static bool CanBeHandled(RegExpTree* tree, JSRegExp::Flags flags,
static bool CanBeHandled(RegExpTree* tree, RegExpFlags flags,
int capture_count);
// Compile regexp into a bytecode program. The regexp must be handlable by
// the experimental engine; see`CanBeHandled`. The program is returned as a
// ZoneList backed by the same Zone that is used in the RegExpTree argument.
static ZoneList<RegExpInstruction> Compile(RegExpTree* tree,
JSRegExp::Flags flags, Zone* zone);
RegExpFlags flags, Zone* zone);
};
} // namespace internal
......
......@@ -5,15 +5,14 @@
#ifndef V8_REGEXP_EXPERIMENTAL_EXPERIMENTAL_INTERPRETER_H_
#define V8_REGEXP_EXPERIMENTAL_EXPERIMENTAL_INTERPRETER_H_
#include "src/base/vector.h"
#include "src/objects/fixed-array.h"
#include "src/objects/string.h"
#include "src/regexp/experimental/experimental-bytecode.h"
#include "src/regexp/regexp.h"
namespace v8 {
namespace internal {
class ByteArray;
class String;
class Zone;
class ExperimentalRegExpInterpreter final : public AllStatic {
......
......@@ -14,7 +14,7 @@
namespace v8 {
namespace internal {
bool ExperimentalRegExp::CanBeHandled(RegExpTree* tree, JSRegExp::Flags flags,
bool ExperimentalRegExp::CanBeHandled(RegExpTree* tree, RegExpFlags flags,
int capture_count) {
DCHECK(FLAG_enable_experimental_regexp_engine ||
FLAG_enable_experimental_regexp_engine_on_excessive_backtracks);
......@@ -22,16 +22,16 @@ bool ExperimentalRegExp::CanBeHandled(RegExpTree* tree, JSRegExp::Flags flags,
}
void ExperimentalRegExp::Initialize(Isolate* isolate, Handle<JSRegExp> re,
Handle<String> source,
JSRegExp::Flags flags, int capture_count) {
Handle<String> source, RegExpFlags flags,
int capture_count) {
DCHECK(FLAG_enable_experimental_regexp_engine);
if (FLAG_trace_experimental_regexp_engine) {
StdoutStream{} << "Initializing experimental regexp " << *source
<< std::endl;
}
isolate->factory()->SetRegExpExperimentalData(re, source, flags,
capture_count);
isolate->factory()->SetRegExpExperimentalData(
re, source, JSRegExp::AsJSRegExpFlags(flags), capture_count);
}
bool ExperimentalRegExp::IsCompiled(Handle<JSRegExp> re, Isolate* isolate) {
......@@ -87,7 +87,7 @@ base::Optional<CompilationResult> CompileImpl(Isolate* isolate,
}
ZoneList<RegExpInstruction> bytecode = ExperimentalRegExpCompiler::Compile(
parse_result.tree, regexp->GetFlags(), &zone);
parse_result.tree, JSRegExp::AsRegExpFlags(regexp->GetFlags()), &zone);
CompilationResult result;
result.bytecode = VectorToByteArray(isolate, bytecode.ToVector());
......
......@@ -5,6 +5,7 @@
#ifndef V8_REGEXP_EXPERIMENTAL_EXPERIMENTAL_H_
#define V8_REGEXP_EXPERIMENTAL_EXPERIMENTAL_H_
#include "src/regexp/regexp-flags.h"
#include "src/regexp/regexp.h"
namespace v8 {
......@@ -19,10 +20,10 @@ class ExperimentalRegExp final : public AllStatic {
// TODO(mbid, v8:10765): This walks the RegExpTree, but it could also be
// checked on the fly in the parser. Not done currently because walking the
// AST again is more flexible and less error prone (but less performant).
static bool CanBeHandled(RegExpTree* tree, JSRegExp::Flags flags,
static bool CanBeHandled(RegExpTree* tree, RegExpFlags flags,
int capture_count);
static void Initialize(Isolate* isolate, Handle<JSRegExp> re,
Handle<String> pattern, JSRegExp::Flags flags,
Handle<String> pattern, RegExpFlags flags,
int capture_count);
static bool IsCompiled(Handle<JSRegExp> re, Isolate* isolate);
V8_WARN_UNUSED_RESULT
......
......@@ -6,10 +6,7 @@
#define V8_REGEXP_REGEXP_AST_H_
#include "src/base/strings.h"
#include "src/objects/js-regexp.h"
#include "src/objects/objects.h"
#include "src/objects/string.h"
#include "src/utils/utils.h"
#include "src/regexp/regexp-flags.h"
#include "src/zone/zone-containers.h"
#include "src/zone/zone-list.h"
#include "src/zone/zone.h"
......@@ -96,13 +93,14 @@ class CharacterRange {
static inline CharacterRange Singleton(base::uc32 value) {
return CharacterRange(value, value);
}
static constexpr int kMaxCodePoint = 0x10ffff;
static inline CharacterRange Range(base::uc32 from, base::uc32 to) {
DCHECK(0 <= from && to <= String::kMaxCodePoint);
DCHECK(0 <= from && to <= kMaxCodePoint);
DCHECK(static_cast<uint32_t>(from) <= static_cast<uint32_t>(to));
return CharacterRange(from, to);
}
static inline CharacterRange Everything() {
return CharacterRange(0, String::kMaxCodePoint);
return CharacterRange(0, kMaxCodePoint);
}
static inline ZoneList<CharacterRange>* List(Zone* zone,
CharacterRange range) {
......@@ -566,9 +564,9 @@ class RegExpLookaround final : public RegExpTree {
class RegExpBackReference final : public RegExpTree {
public:
explicit RegExpBackReference(JSRegExp::Flags flags)
explicit RegExpBackReference(RegExpFlags flags)
: capture_(nullptr), name_(nullptr), flags_(flags) {}
RegExpBackReference(RegExpCapture* capture, JSRegExp::Flags flags)
RegExpBackReference(RegExpCapture* capture, RegExpFlags flags)
: capture_(capture), name_(nullptr), flags_(flags) {}
void* Accept(RegExpVisitor* visitor, void* data) override;
RegExpNode* ToNode(RegExpCompiler* compiler, RegExpNode* on_success) override;
......@@ -587,7 +585,7 @@ class RegExpBackReference final : public RegExpTree {
private:
RegExpCapture* capture_;
const ZoneVector<base::uc16>* name_;
const JSRegExp::Flags flags_;
const RegExpFlags flags_;
};
......
......@@ -7,7 +7,6 @@
#include "src/regexp/regexp-bytecode-generator.h"
#include "src/ast/ast.h"
#include "src/regexp/regexp-bytecodes.h"
namespace v8 {
......
......@@ -5,7 +5,7 @@
#include "src/regexp/regexp-bytecode-generator.h"
#include "src/ast/ast.h"
#include "src/objects/objects-inl.h"
#include "src/objects/fixed-array-inl.h"
#include "src/regexp/regexp-bytecode-generator-inl.h"
#include "src/regexp/regexp-bytecode-peephole.h"
#include "src/regexp/regexp-bytecodes.h"
......
......@@ -6,6 +6,7 @@
#define V8_REGEXP_REGEXP_BYTECODE_GENERATOR_H_
#include "src/base/strings.h"
#include "src/codegen/label.h"
#include "src/regexp/regexp-macro-assembler.h"
namespace v8 {
......
......@@ -4,10 +4,8 @@
#include "src/regexp/regexp-bytecode-peephole.h"
#include "src/execution/isolate.h"
#include "src/flags/flags.h"
#include "src/objects/fixed-array.h"
#include "src/objects/objects-inl.h"
#include "src/objects/fixed-array-inl.h"
#include "src/regexp/regexp-bytecodes.h"
#include "src/utils/memcopy.h"
#include "src/utils/utils.h"
......
......@@ -6,14 +6,12 @@
#include "src/execution/isolate.h"
#include "src/regexp/regexp.h"
#ifdef V8_INTL_SUPPORT
#include "src/regexp/special-case.h"
#endif // V8_INTL_SUPPORT
#include "src/strings/unicode-inl.h"
#include "src/zone/zone-list-inl.h"
#ifdef V8_INTL_SUPPORT
#include "src/base/strings.h"
#include "src/regexp/special-case.h"
#include "unicode/locid.h"
#include "unicode/uniset.h"
#include "unicode/utypes.h"
......@@ -24,6 +22,11 @@ namespace internal {
using namespace regexp_compiler_constants; // NOLINT(build/namespaces)
constexpr base::uc32 kMaxCodePoint = 0x10ffff;
constexpr int kMaxUtf16CodeUnit = 0xffff;
constexpr uint32_t kMaxUtf16CodeUnitU = 0xffff;
constexpr int32_t kMaxOneByteCharCode = unibrow::Latin1::kMaxChar;
// -------------------------------------------------------------------
// Tree to graph conversion
......@@ -65,7 +68,7 @@ static bool CompareInverseRanges(ZoneList<CharacterRange>* ranges,
return false;
}
}
if (range.to() != String::kMaxCodePoint) {
if (range.to() != kMaxCodePoint) {
return false;
}
return true;
......@@ -359,8 +362,8 @@ RegExpNode* UnanchoredAdvance(RegExpCompiler* compiler,
// we advanced into the middle of a surrogate pair, it will work out, as
// nothing will match from there. We will have to advance again, consuming
// the associated trail surrogate.
ZoneList<CharacterRange>* range = CharacterRange::List(
zone, CharacterRange::Range(0, String::kMaxUtf16CodeUnit));
ZoneList<CharacterRange>* range =
CharacterRange::List(zone, CharacterRange::Range(0, kMaxUtf16CodeUnit));
return TextNode::CreateForCharacterRanges(zone, range, false, on_success);
}
......@@ -658,7 +661,7 @@ void RegExpDisjunction::FixSingleCharacterDisjunctions(
i++;
continue;
}
const JSRegExp::Flags flags = compiler->flags();
const RegExpFlags flags = compiler->flags();
DCHECK_IMPLIES(IsUnicode(flags),
!unibrow::Utf16::IsLeadSurrogate(atom->data().at(0)));
bool contains_trail_surrogate =
......@@ -740,7 +743,7 @@ namespace {
RegExpNode* BoundaryAssertionAsLookaround(RegExpCompiler* compiler,
RegExpNode* on_success,
RegExpAssertion::AssertionType type,
JSRegExp::Flags flags) {
RegExpFlags flags) {
CHECK(NeedsUnicodeCaseEquivalents(flags));
Zone* zone = compiler->zone();
ZoneList<CharacterRange>* word_range =
......@@ -1038,7 +1041,7 @@ static void AddClassNegated(const int* elmv, int elmc,
elmc--;
DCHECK_EQ(kRangeEndMarker, elmv[elmc]);
DCHECK_NE(0x0000, elmv[0]);
DCHECK_NE(String::kMaxCodePoint, elmv[elmc - 1]);
DCHECK_NE(kMaxCodePoint, elmv[elmc - 1]);
base::uc16 last = 0x0000;
for (int i = 0; i < elmc; i += 2) {
DCHECK(last <= elmv[i] - 1);
......@@ -1046,7 +1049,7 @@ static void AddClassNegated(const int* elmv, int elmc,
ranges->Add(CharacterRange::Range(last, elmv[i] - 1), zone);
last = elmv[i + 1];
}
ranges->Add(CharacterRange::Range(last, String::kMaxCodePoint), zone);
ranges->Add(CharacterRange::Range(last, kMaxCodePoint), zone);
}
void CharacterRange::AddClassEscape(char type, ZoneList<CharacterRange>* ranges,
......@@ -1128,13 +1131,13 @@ void CharacterRange::AddCaseEquivalents(Isolate* isolate, Zone* zone,
for (int i = 0; i < range_count; i++) {
CharacterRange range = ranges->at(i);
base::uc32 from = range.from();
if (from > String::kMaxUtf16CodeUnit) continue;
base::uc32 to = std::min({range.to(), String::kMaxUtf16CodeUnitU});
if (from > kMaxUtf16CodeUnit) continue;
base::uc32 to = std::min({range.to(), kMaxUtf16CodeUnitU});
// Nothing to be done for surrogates.
if (from >= kLeadSurrogateStart && to <= kTrailSurrogateEnd) continue;
if (is_one_byte && !RangeContainsLatin1Equivalents(range)) {
if (from > String::kMaxOneByteCharCode) continue;
if (to > String::kMaxOneByteCharCode) to = String::kMaxOneByteCharCode;
if (from > kMaxOneByteCharCode) continue;
if (to > kMaxOneByteCharCode) to = kMaxOneByteCharCode;
}
others.add(from, to);
}
......@@ -1171,13 +1174,13 @@ void CharacterRange::AddCaseEquivalents(Isolate* isolate, Zone* zone,
for (int i = 0; i < range_count; i++) {
CharacterRange range = ranges->at(i);
base::uc32 bottom = range.from();
if (bottom > String::kMaxUtf16CodeUnit) continue;
base::uc32 top = std::min({range.to(), String::kMaxUtf16CodeUnitU});
if (bottom > kMaxUtf16CodeUnit) continue;
base::uc32 top = std::min({range.to(), kMaxUtf16CodeUnitU});
// Nothing to be done for surrogates.
if (bottom >= kLeadSurrogateStart && top <= kTrailSurrogateEnd) continue;
if (is_one_byte && !RangeContainsLatin1Equivalents(range)) {
if (bottom > String::kMaxOneByteCharCode) continue;
if (top > String::kMaxOneByteCharCode) top = String::kMaxOneByteCharCode;
if (bottom > kMaxOneByteCharCode) continue;
if (top > kMaxOneByteCharCode) top = kMaxOneByteCharCode;
}
unibrow::uchar chars[unibrow::Ecma262UnCanonicalize::kMaxWidth];
if (top == bottom) {
......@@ -1389,9 +1392,8 @@ void CharacterRange::Negate(ZoneList<CharacterRange>* ranges,
from = range.to() + 1;
i++;
}
if (from < String::kMaxCodePoint) {
negated_ranges->Add(CharacterRange::Range(from, String::kMaxCodePoint),
zone);
if (from < kMaxCodePoint) {
negated_ranges->Add(CharacterRange::Range(from, kMaxCodePoint), zone);
}
}
......
......@@ -6,15 +6,13 @@
#include "src/base/safe_conversions.h"
#include "src/execution/isolate.h"
#include "src/objects/objects-inl.h"
#include "src/objects/fixed-array-inl.h"
#include "src/regexp/regexp-macro-assembler-arch.h"
#ifdef V8_INTL_SUPPORT
#include "src/regexp/special-case.h"
#endif // V8_INTL_SUPPORT
#include "src/strings/unicode-inl.h"
#include "src/zone/zone-list-inl.h"
#ifdef V8_INTL_SUPPORT
#include "src/regexp/special-case.h"
#include "unicode/locid.h"
#include "unicode/uniset.h"
#include "unicode/utypes.h"
......@@ -240,7 +238,7 @@ class RecursionCheck {
// Attempts to compile the regexp using an Irregexp code generator. Returns
// a fixed array or a null handle depending on whether it succeeded.
RegExpCompiler::RegExpCompiler(Isolate* isolate, Zone* zone, int capture_count,
JSRegExp::Flags flags, bool one_byte)
RegExpFlags flags, bool one_byte)
: next_register_(JSRegExp::RegistersForCaptureCount(capture_count)),
unicode_lookaround_stack_register_(kNoRegister),
unicode_lookaround_position_register_(kNoRegister),
......@@ -1819,7 +1817,7 @@ class IterationDecrementer {
LoopChoiceNode* node_;
};
RegExpNode* SeqRegExpNode::FilterOneByte(int depth, JSRegExp::Flags flags) {
RegExpNode* SeqRegExpNode::FilterOneByte(int depth, RegExpFlags flags) {
if (info()->replacement_calculated) return replacement();
if (depth < 0) return this;
DCHECK(!info()->visited);
......@@ -1827,7 +1825,7 @@ RegExpNode* SeqRegExpNode::FilterOneByte(int depth, JSRegExp::Flags flags) {
return FilterSuccessor(depth - 1, flags);
}
RegExpNode* SeqRegExpNode::FilterSuccessor(int depth, JSRegExp::Flags flags) {
RegExpNode* SeqRegExpNode::FilterSuccessor(int depth, RegExpFlags flags) {
RegExpNode* next = on_success_->FilterOneByte(depth - 1, flags);
if (next == nullptr) return set_replacement(nullptr);
on_success_ = next;
......@@ -1849,7 +1847,7 @@ static bool RangesContainLatin1Equivalents(ZoneList<CharacterRange>* ranges) {
return false;
}
RegExpNode* TextNode::FilterOneByte(int depth, JSRegExp::Flags flags) {
RegExpNode* TextNode::FilterOneByte(int depth, RegExpFlags flags) {
if (info()->replacement_calculated) return replacement();
if (depth < 0) return this;
DCHECK(!info()->visited);
......@@ -1900,7 +1898,7 @@ RegExpNode* TextNode::FilterOneByte(int depth, JSRegExp::Flags flags) {
return FilterSuccessor(depth - 1, flags);
}
RegExpNode* LoopChoiceNode::FilterOneByte(int depth, JSRegExp::Flags flags) {
RegExpNode* LoopChoiceNode::FilterOneByte(int depth, RegExpFlags flags) {
if (info()->replacement_calculated) return replacement();
if (depth < 0) return this;
if (info()->visited) return this;
......@@ -1917,7 +1915,7 @@ RegExpNode* LoopChoiceNode::FilterOneByte(int depth, JSRegExp::Flags flags) {
return ChoiceNode::FilterOneByte(depth - 1, flags);
}
RegExpNode* ChoiceNode::FilterOneByte(int depth, JSRegExp::Flags flags) {
RegExpNode* ChoiceNode::FilterOneByte(int depth, RegExpFlags flags) {
if (info()->replacement_calculated) return replacement();
if (depth < 0) return this;
if (info()->visited) return this;
......@@ -1969,7 +1967,7 @@ RegExpNode* ChoiceNode::FilterOneByte(int depth, JSRegExp::Flags flags) {
}
RegExpNode* NegativeLookaroundChoiceNode::FilterOneByte(int depth,
JSRegExp::Flags flags) {
RegExpFlags flags) {
if (info()->replacement_calculated) return replacement();
if (depth < 0) return this;
if (info()->visited) return this;
......@@ -2491,7 +2489,7 @@ void Trace::AdvanceCurrentPositionInTrace(int by, RegExpCompiler* compiler) {
}
void TextNode::MakeCaseIndependent(Isolate* isolate, bool is_one_byte,
JSRegExp::Flags flags) {
RegExpFlags flags) {
if (!IsIgnoreCase(flags)) return;
#ifdef V8_INTL_SUPPORT
if (NeedsUnicodeCaseEquivalents(flags)) return;
......@@ -3634,7 +3632,7 @@ class EatsAtLeastPropagator : public AllStatic {
template <typename... Propagators>
class Analysis : public NodeVisitor {
public:
Analysis(Isolate* isolate, bool is_one_byte, JSRegExp::Flags flags)
Analysis(Isolate* isolate, bool is_one_byte, RegExpFlags flags)
: isolate_(isolate),
is_one_byte_(is_one_byte),
flags_(flags),
......@@ -3746,14 +3744,14 @@ class Analysis : public NodeVisitor {
private:
Isolate* isolate_;
const bool is_one_byte_;
const JSRegExp::Flags flags_;
const RegExpFlags flags_;
RegExpError error_;
DISALLOW_IMPLICIT_CONSTRUCTORS(Analysis);
};
RegExpError AnalyzeRegExp(Isolate* isolate, bool is_one_byte,
JSRegExp::Flags flags, RegExpNode* node) {
RegExpError AnalyzeRegExp(Isolate* isolate, bool is_one_byte, RegExpFlags flags,
RegExpNode* node) {
Analysis<AssertionPropagator, EatsAtLeastPropagator> analysis(
isolate, is_one_byte, flags);
DCHECK_EQ(node->info()->been_analyzed, false);
......@@ -3874,7 +3872,7 @@ RegExpNode* RegExpCompiler::OptionallyStepBackToLeadSurrogate(
}
RegExpNode* RegExpCompiler::PreprocessRegExp(RegExpCompileData* data,
JSRegExp::Flags flags,
RegExpFlags flags,
bool is_one_byte) {
// Wrap the body of the regexp in capture #0.
RegExpNode* captured_body =
......
......@@ -50,14 +50,7 @@ constexpr int kPatternTooShortForBoyerMoore = 2;
} // namespace regexp_compiler_constants
#define V(Lower, Camel, LowerCamel, Char, Bit) \
inline bool Is##Camel(JSRegExp::Flags flags) { \
return Is##Camel(JSRegExp::AsRegExpFlags(flags)); \
}
REGEXP_FLAG_LIST(V)
#undef V
inline bool NeedsUnicodeCaseEquivalents(JSRegExp::Flags flags) {
inline bool NeedsUnicodeCaseEquivalents(RegExpFlags flags) {
// Both unicode and ignore_case flags are set. We need to use ICU to find
// the closure over case equivalents.
return IsUnicode(flags) && IsIgnoreCase(flags);
......@@ -408,8 +401,8 @@ struct PreloadState {
// Analysis performs assertion propagation and computes eats_at_least_ values.
// See the comments on AssertionPropagator and EatsAtLeastPropagator for more
// details.
RegExpError AnalyzeRegExp(Isolate* isolate, bool is_one_byte,
JSRegExp::Flags flags, RegExpNode* node);
RegExpError AnalyzeRegExp(Isolate* isolate, bool is_one_byte, RegExpFlags flags,
RegExpNode* node);
class FrequencyCollator {
public:
......@@ -459,7 +452,7 @@ class FrequencyCollator {
class RegExpCompiler {
public:
RegExpCompiler(Isolate* isolate, Zone* zone, int capture_count,
JSRegExp::Flags flags, bool is_one_byte);
RegExpFlags flags, bool is_one_byte);
int AllocateRegister() {
if (next_register_ >= RegExpMacroAssembler::kMaxRegister) {
......@@ -511,7 +504,7 @@ class RegExpCompiler {
// - Inserting the implicit .* before/after the regexp if necessary.
// - If the input is a one-byte string, filtering out nodes that can't match.
// - Fixing up regexp matches that start within a surrogate pair.
RegExpNode* PreprocessRegExp(RegExpCompileData* data, JSRegExp::Flags flags,
RegExpNode* PreprocessRegExp(RegExpCompileData* data, RegExpFlags flags,
bool is_one_byte);
// If the regexp matching starts within a surrogate pair, step back to the
......@@ -537,7 +530,7 @@ class RegExpCompiler {
inline void IncrementRecursionDepth() { recursion_depth_++; }
inline void DecrementRecursionDepth() { recursion_depth_--; }
JSRegExp::Flags flags() const { return flags_; }
RegExpFlags flags() const { return flags_; }
void SetRegExpTooBig() { reg_exp_too_big_ = true; }
......@@ -569,7 +562,7 @@ class RegExpCompiler {
int unicode_lookaround_position_register_;
ZoneVector<RegExpNode*>* work_list_;
int recursion_depth_;
const JSRegExp::Flags flags_;
const RegExpFlags flags_;
RegExpMacroAssembler* macro_assembler_;
bool one_byte_;
bool reg_exp_too_big_;
......
......@@ -11,6 +11,9 @@
namespace v8 {
namespace internal {
// TODO(jgruber,pthier): Decouple more parts of the codebase from
// JSRegExp::Flags. Consider removing JSRegExp::Flags.
// Order is important! Sorted in alphabetic order by the flag char. Note this
// means that flag bits are shuffled. Take care to keep them contiguous when
// adding/removing flags.
......@@ -44,6 +47,7 @@ static_assert(((1 << kRegExpFlagCount) - 1) == (0 REGEXP_FLAG_LIST(V)),
#undef V
using RegExpFlags = base::Flags<RegExpFlag>;
DEFINE_OPERATORS_FOR_FLAGS(RegExpFlags)
#define V(Lower, Camel, ...) \
constexpr bool Is##Camel(RegExpFlags f) { \
......
......@@ -6,17 +6,18 @@
#include "src/regexp/regexp-interpreter.h"
#include "src/ast/ast.h"
#include "src/base/small-vector.h"
#include "src/base/strings.h"
#include "src/execution/isolate.h"
#include "src/logging/counters.h"
#include "src/objects/js-regexp-inl.h"
#include "src/objects/objects-inl.h"
#include "src/objects/string-inl.h"
#include "src/regexp/regexp-bytecodes.h"
#include "src/regexp/regexp-macro-assembler.h"
#include "src/regexp/regexp-stack.h" // For kMaximumStackSize.
#include "src/regexp/regexp.h"
#include "src/strings/unicode.h"
#include "src/utils/memcopy.h"
#include "src/utils/utils.h"
#ifdef V8_INTL_SUPPORT
......
......@@ -12,6 +12,8 @@
namespace v8 {
namespace internal {
class ByteArray;
class V8_EXPORT_PRIVATE IrregexpInterpreter : public AllStatic {
public:
enum Result {
......
......@@ -4,8 +4,8 @@
#include "src/regexp/regexp-macro-assembler-tracer.h"
#include "src/ast/ast.h"
#include "src/objects/objects-inl.h"
#include "src/objects/fixed-array-inl.h"
#include "src/objects/string.h"
namespace v8 {
namespace internal {
......
......@@ -5,6 +5,7 @@
#include "src/regexp/regexp-macro-assembler.h"
#include "src/codegen/assembler.h"
#include "src/codegen/label.h"
#include "src/execution/isolate-inl.h"
#include "src/execution/pointer-authentication.h"
#include "src/execution/simulator.h"
......@@ -22,12 +23,17 @@ namespace internal {
RegExpMacroAssembler::RegExpMacroAssembler(Isolate* isolate, Zone* zone)
: slow_safe_compiler_(false),
backtrack_limit_(JSRegExp::kNoBacktrackLimit),
global_mode_(NOT_GLOBAL),
isolate_(isolate),
zone_(zone) {}
RegExpMacroAssembler::~RegExpMacroAssembler() = default;
bool RegExpMacroAssembler::has_backtrack_limit() const {
return backtrack_limit_ != JSRegExp::kNoBacktrackLimit;
}
int RegExpMacroAssembler::CaseInsensitiveCompareNonUnicode(Address byte_offset1,
Address byte_offset2,
size_t byte_length,
......
......@@ -6,13 +6,15 @@
#define V8_REGEXP_REGEXP_MACRO_ASSEMBLER_H_
#include "src/base/strings.h"
#include "src/codegen/label.h"
#include "src/regexp/regexp-ast.h"
#include "src/regexp/regexp.h"
namespace v8 {
namespace internal {
class ByteArray;
class Label;
static const base::uc32 kLeadSurrogateStart = 0xd800;
static const base::uc32 kLeadSurrogateEnd = 0xdbff;
static const base::uc32 kTrailSurrogateStart = 0xdc00;
......@@ -231,20 +233,18 @@ class RegExpMacroAssembler {
Zone* zone() const { return zone_; }
protected:
bool has_backtrack_limit() const {
return backtrack_limit_ != JSRegExp::kNoBacktrackLimit;
}
bool has_backtrack_limit() const;
uint32_t backtrack_limit() const { return backtrack_limit_; }
bool can_fallback() const { return can_fallback_; }
private:
bool slow_safe_compiler_;
uint32_t backtrack_limit_ = JSRegExp::kNoBacktrackLimit;
uint32_t backtrack_limit_;
bool can_fallback_ = false;
GlobalMode global_mode_;
Isolate* isolate_;
Zone* zone_;
Isolate* const isolate_;
Zone* const zone_;
};
class NativeRegExpMacroAssembler: public RegExpMacroAssembler {
......
......@@ -5,6 +5,7 @@
#ifndef V8_REGEXP_REGEXP_NODES_H_
#define V8_REGEXP_REGEXP_NODES_H_
#include "src/codegen/label.h"
#include "src/regexp/regexp-macro-assembler.h"
#include "src/zone/zone.h"
......@@ -14,7 +15,6 @@ namespace internal {
class AlternativeGenerationList;
class BoyerMooreLookahead;
class GreedyLoopState;
class Label;
class NodeVisitor;
class QuickCheckDetails;
class RegExpCompiler;
......@@ -205,7 +205,7 @@ class RegExpNode : public ZoneObject {
// If we know that the input is one-byte then there are some nodes that can
// never match. This method returns a node that can be substituted for
// itself, or nullptr if the node can never match.
virtual RegExpNode* FilterOneByte(int depth, JSRegExp::Flags flags) {
virtual RegExpNode* FilterOneByte(int depth, RegExpFlags flags) {
return this;
}
// Helper for FilterOneByte.
......@@ -296,7 +296,7 @@ class SeqRegExpNode : public RegExpNode {
: RegExpNode(on_success->zone()), on_success_(on_success) {}
RegExpNode* on_success() { return on_success_; }
void set_on_success(RegExpNode* node) { on_success_ = node; }
RegExpNode* FilterOneByte(int depth, JSRegExp::Flags flags) override;
RegExpNode* FilterOneByte(int depth, RegExpFlags flags) override;
void FillInBMInfo(Isolate* isolate, int offset, int budget,
BoyerMooreLookahead* bm, bool not_at_start) override {
on_success_->FillInBMInfo(isolate, offset, budget - 1, bm, not_at_start);
......@@ -304,7 +304,7 @@ class SeqRegExpNode : public RegExpNode {
}
protected:
RegExpNode* FilterSuccessor(int depth, JSRegExp::Flags flags);
RegExpNode* FilterSuccessor(int depth, RegExpFlags flags);
private:
RegExpNode* on_success_;
......@@ -423,14 +423,14 @@ class TextNode : public SeqRegExpNode {
ZoneList<TextElement>* elements() { return elms_; }
bool read_backward() { return read_backward_; }
void MakeCaseIndependent(Isolate* isolate, bool is_one_byte,
JSRegExp::Flags flags);
RegExpFlags flags);
int GreedyLoopTextLength() override;
RegExpNode* GetSuccessorOfOmnivorousTextNode(
RegExpCompiler* compiler) override;
void FillInBMInfo(Isolate* isolate, int offset, int budget,
BoyerMooreLookahead* bm, bool not_at_start) override;
void CalculateOffsets();
RegExpNode* FilterOneByte(int depth, JSRegExp::Flags flags) override;
RegExpNode* FilterOneByte(int depth, RegExpFlags flags) override;
int Length();
private:
......@@ -498,7 +498,7 @@ class AssertionNode : public SeqRegExpNode {
class BackReferenceNode : public SeqRegExpNode {
public:
BackReferenceNode(int start_reg, int end_reg, JSRegExp::Flags flags,
BackReferenceNode(int start_reg, int end_reg, RegExpFlags flags,
bool read_backward, RegExpNode* on_success)
: SeqRegExpNode(on_success),
start_reg_(start_reg),
......@@ -521,7 +521,7 @@ class BackReferenceNode : public SeqRegExpNode {
private:
int start_reg_;
int end_reg_;
JSRegExp::Flags flags_;
RegExpFlags flags_;
bool read_backward_;
};
......@@ -623,7 +623,7 @@ class ChoiceNode : public RegExpNode {
virtual bool try_to_emit_quick_check_for_alternative(bool is_first) {
return true;
}
RegExpNode* FilterOneByte(int depth, JSRegExp::Flags flags) override;
RegExpNode* FilterOneByte(int depth, RegExpFlags flags) override;
virtual bool read_backward() { return false; }
protected:
......@@ -695,7 +695,7 @@ class NegativeLookaroundChoiceNode : public ChoiceNode {
return !is_first;
}
void Accept(NodeVisitor* visitor) override;
RegExpNode* FilterOneByte(int depth, JSRegExp::Flags flags) override;
RegExpNode* FilterOneByte(int depth, RegExpFlags flags) override;
};
class LoopChoiceNode : public ChoiceNode {
......@@ -728,7 +728,7 @@ class LoopChoiceNode : public ChoiceNode {
int min_loop_iterations() const { return min_loop_iterations_; }
bool read_backward() override { return read_backward_; }
void Accept(NodeVisitor* visitor) override;
RegExpNode* FilterOneByte(int depth, JSRegExp::Flags flags) override;
RegExpNode* FilterOneByte(int depth, RegExpFlags flags) override;
private:
// AddAlternative is made private for loop nodes because alternatives
......
......@@ -139,7 +139,7 @@ class RegExpBuilder : public ZoneObject {
bool NeedsDesugaringForUnicode(RegExpCharacterClass* cc);
bool NeedsDesugaringForIgnoreCase(base::uc32 c);
Zone* zone() const { return zone_; }
bool unicode() const { return (flags_ & JSRegExp::kUnicode) != 0; }
bool unicode() const { return IsUnicode(flags_); }
Zone* const zone_;
bool pending_empty_;
......@@ -303,9 +303,7 @@ class RegExpParserImpl final {
int captures_started() { return captures_started_; }
int position() { return next_pos_ - 1; }
bool failed() { return failed_; }
// The Unicode flag can't be changed using in-regexp syntax, so it's OK to
// just read the initial flag value here.
bool unicode() const { return (top_level_flags_ & JSRegExp::kUnicode) != 0; }
bool unicode() const { return IsUnicode(top_level_flags_); }
static bool IsSyntaxCharacterOrSlash(base::uc32 c);
......@@ -374,9 +372,6 @@ class RegExpParserImpl final {
const CharT* const input_;
const int input_length_;
base::uc32 current_;
// These are the flags specified outside the regexp syntax ie after the
// terminating '/' or in the second argument to the constructor. The current
// flags are stored on the RegExpBuilder.
const RegExpFlags top_level_flags_;
int next_pos_;
int captures_started_;
......@@ -777,7 +772,7 @@ RegExpTree* RegExpParserImpl<CharT>::ParseDisjunction() {
} else {
RegExpCapture* capture = GetCapture(index);
RegExpTree* atom = zone()->template New<RegExpBackReference>(
capture, JSRegExp::AsJSRegExpFlags(builder->flags()));
capture, builder->flags());
builder->AddAtom(atom);
}
break;
......@@ -1017,7 +1012,7 @@ RegExpParserState* RegExpParserImpl<CharT>::ParseOpenParenthesis(
}
}
if (subexpr_type == CAPTURE) {
if (captures_started_ >= JSRegExp::kMaxCaptures) {
if (captures_started_ >= RegExpMacroAssembler::kMaxRegisterCount) {
ReportError(RegExpError::kTooManyCaptures);
return nullptr;
}
......@@ -1124,7 +1119,7 @@ bool RegExpParserImpl<CharT>::ParseBackReferenceIndex(int* index_out) {
base::uc32 c = current();
if (IsDecimalDigit(c)) {
value = 10 * value + (c - '0');
if (value > JSRegExp::kMaxCaptures) {
if (value > RegExpMacroAssembler::kMaxRegisterCount) {
Reset(start);
return false;
}
......@@ -1252,8 +1247,8 @@ bool RegExpParserImpl<CharT>::ParseNamedBackReference(
if (state->IsInsideCaptureGroup(name)) {
builder->AddEmpty();
} else {
RegExpBackReference* atom = zone()->template New<RegExpBackReference>(
JSRegExp::AsJSRegExpFlags(builder->flags()));
RegExpBackReference* atom =
zone()->template New<RegExpBackReference>(builder->flags());
atom->set_name(name);
builder->AddAtom(atom);
......
......@@ -120,33 +120,6 @@ MaybeHandle<Object> RegExpUtils::RegExpExec(Isolate* isolate,
}
}
Maybe<bool> RegExpUtils::IsRegExp(Isolate* isolate, Handle<Object> object) {
if (!object->IsJSReceiver()) return Just(false);
Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(object);
Handle<Object> match;
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
isolate, match,
JSObject::GetProperty(isolate, receiver,
isolate->factory()->match_symbol()),
Nothing<bool>());
if (!match->IsUndefined(isolate)) {
const bool match_as_boolean = match->BooleanValue(isolate);
if (match_as_boolean && !object->IsJSRegExp()) {
isolate->CountUsage(v8::Isolate::kRegExpMatchIsTrueishOnNonJSRegExp);
} else if (!match_as_boolean && object->IsJSRegExp()) {
isolate->CountUsage(v8::Isolate::kRegExpMatchIsFalseishOnJSRegExp);
}
return Just(match_as_boolean);
}
return Just(object->IsJSRegExp());
}
bool RegExpUtils::IsUnmodifiedRegExp(Isolate* isolate, Handle<Object> obj) {
#ifdef V8_ENABLE_FORCE_SLOW_PATH
if (isolate->force_slow_path()) return false;
......
......@@ -5,12 +5,15 @@
#ifndef V8_REGEXP_REGEXP_UTILS_H_
#define V8_REGEXP_REGEXP_UTILS_H_
#include "src/objects/objects.h"
#include "src/common/globals.h"
namespace v8 {
namespace internal {
class JSReceiver;
class Object;
class RegExpMatchInfo;
class String;
// Helper methods for C++ regexp builtins.
class RegExpUtils : public AllStatic {
......@@ -31,10 +34,6 @@ class RegExpUtils : public AllStatic {
Isolate* isolate, Handle<JSReceiver> regexp, Handle<String> string,
Handle<Object> exec);
// ES#sec-isregexp IsRegExp ( argument )
// Includes checking of the match property.
static Maybe<bool> IsRegExp(Isolate* isolate, Handle<Object> object);
// Checks whether the given object is an unmodified JSRegExp instance.
// Neither the object's map, nor its prototype's map, nor any relevant
// method on the prototype may be modified.
......
......@@ -37,7 +37,7 @@ class RegExpImpl final : public AllStatic {
// Prepares a JSRegExp object with Irregexp-specific data.
static void IrregexpInitialize(Isolate* isolate, Handle<JSRegExp> re,
Handle<String> pattern, JSRegExp::Flags flags,
Handle<String> pattern, RegExpFlags flags,
int capture_count, uint32_t backtrack_limit);
// Prepare a RegExp for being executed one or more times (using
......@@ -51,7 +51,7 @@ class RegExpImpl final : public AllStatic {
Handle<String> subject);
static void AtomCompile(Isolate* isolate, Handle<JSRegExp> re,
Handle<String> pattern, JSRegExp::Flags flags,
Handle<String> pattern, RegExpFlags flags,
Handle<String> match_pattern);
static int AtomExecRaw(Isolate* isolate, Handle<JSRegExp> regexp,
......@@ -90,7 +90,7 @@ class RegExpImpl final : public AllStatic {
// Returns true on success, false on failure.
static bool Compile(Isolate* isolate, Zone* zone, RegExpCompileData* input,
JSRegExp::Flags flags, Handle<String> pattern,
RegExpFlags flags, Handle<String> pattern,
Handle<String> sample_subject, bool is_one_byte,
uint32_t& backtrack_limit);
......@@ -102,6 +102,11 @@ class RegExpImpl final : public AllStatic {
static Code IrregexpNativeCode(FixedArray re, bool is_one_byte);
};
// static
bool RegExp::CanGenerateBytecode() {
return FLAG_regexp_interpret_all || FLAG_regexp_tier_up;
}
MaybeHandle<Object> RegExp::ThrowRegExpException(Isolate* isolate,
Handle<JSRegExp> re,
Handle<String> pattern,
......@@ -154,8 +159,7 @@ static bool HasFewDifferentCharacters(Handle<String> pattern) {
// static
MaybeHandle<Object> RegExp::Compile(Isolate* isolate, Handle<JSRegExp> re,
Handle<String> pattern,
JSRegExp::Flags flags,
Handle<String> pattern, RegExpFlags flags,
uint32_t backtrack_limit) {
DCHECK(pattern->IsFlat());
......@@ -169,8 +173,8 @@ MaybeHandle<Object> RegExp::Compile(Isolate* isolate, Handle<JSRegExp> re,
CompilationCache* compilation_cache = nullptr;
if (is_compilation_cache_enabled) {
compilation_cache = isolate->compilation_cache();
MaybeHandle<FixedArray> maybe_cached =
compilation_cache->LookupRegExp(pattern, flags);
MaybeHandle<FixedArray> maybe_cached = compilation_cache->LookupRegExp(
pattern, JSRegExp::AsJSRegExpFlags(flags));
Handle<FixedArray> cached;
if (maybe_cached.ToHandle(&cached)) {
re->set_data(*cached);
......@@ -181,8 +185,7 @@ MaybeHandle<Object> RegExp::Compile(Isolate* isolate, Handle<JSRegExp> re,
PostponeInterruptsScope postpone(isolate);
RegExpCompileData parse_result;
DCHECK(!isolate->has_pending_exception());
if (!RegExpParser::ParseRegExpFromHeapString(isolate, &zone, pattern,
JSRegExp::AsRegExpFlags(flags),
if (!RegExpParser::ParseRegExpFromHeapString(isolate, &zone, pattern, flags,
&parse_result)) {
// Throw an exception if we fail to parse the pattern.
return RegExp::ThrowRegExpException(isolate, re, pattern,
......@@ -239,7 +242,8 @@ MaybeHandle<Object> RegExp::Compile(Isolate* isolate, Handle<JSRegExp> re,
// and we can store it in the cache.
Handle<FixedArray> data(FixedArray::cast(re->data()), isolate);
if (is_compilation_cache_enabled) {
compilation_cache->PutRegExp(pattern, flags, data);
compilation_cache->PutRegExp(pattern, JSRegExp::AsJSRegExpFlags(flags),
data);
}
return re;
......@@ -301,9 +305,10 @@ MaybeHandle<Object> RegExp::Exec(Isolate* isolate, Handle<JSRegExp> regexp,
// RegExp Atom implementation: Simple string search using indexOf.
void RegExpImpl::AtomCompile(Isolate* isolate, Handle<JSRegExp> re,
Handle<String> pattern, JSRegExp::Flags flags,
Handle<String> pattern, RegExpFlags flags,
Handle<String> match_pattern) {
isolate->factory()->SetRegExpAtomData(re, pattern, flags, match_pattern);
isolate->factory()->SetRegExpAtomData(
re, pattern, JSRegExp::AsJSRegExpFlags(flags), match_pattern);
}
static void SetAtomLastCapture(Isolate* isolate,
......@@ -502,13 +507,12 @@ bool RegExpImpl::CompileIrregexp(Isolate* isolate, Handle<JSRegExp> re,
DCHECK(RegExpCodeIsValidForPreCompilation(re, is_one_byte));
JSRegExp::Flags flags = re->GetFlags();
RegExpFlags flags = JSRegExp::AsRegExpFlags(re->GetFlags());
Handle<String> pattern(re->Pattern(), isolate);
pattern = String::Flatten(isolate, pattern);
RegExpCompileData compile_data;
if (!RegExpParser::ParseRegExpFromHeapString(isolate, &zone, pattern,
JSRegExp::AsRegExpFlags(flags),
if (!RegExpParser::ParseRegExpFromHeapString(isolate, &zone, pattern, flags,
&compile_data)) {
// Throw an exception if we fail to parse the pattern.
// THIS SHOULD NOT HAPPEN. We already pre-parsed it successfully once.
......@@ -596,12 +600,13 @@ Code RegExpImpl::IrregexpNativeCode(FixedArray re, bool is_one_byte) {
}
void RegExpImpl::IrregexpInitialize(Isolate* isolate, Handle<JSRegExp> re,
Handle<String> pattern,
JSRegExp::Flags flags, int capture_count,
Handle<String> pattern, RegExpFlags flags,
int capture_count,
uint32_t backtrack_limit) {
// Initialize compiled code entries to null.
isolate->factory()->SetRegExpIrregexpData(re, pattern, flags, capture_count,
backtrack_limit);
isolate->factory()->SetRegExpIrregexpData(re, pattern,
JSRegExp::AsJSRegExpFlags(flags),
capture_count, backtrack_limit);
}
// static
......@@ -826,7 +831,7 @@ bool TooMuchRegExpCode(Isolate* isolate, Handle<String> pattern) {
// static
bool RegExp::CompileForTesting(Isolate* isolate, Zone* zone,
RegExpCompileData* data, JSRegExp::Flags flags,
RegExpCompileData* data, RegExpFlags flags,
Handle<String> pattern,
Handle<String> sample_subject,
bool is_one_byte) {
......@@ -836,7 +841,7 @@ bool RegExp::CompileForTesting(Isolate* isolate, Zone* zone,
}
bool RegExpImpl::Compile(Isolate* isolate, Zone* zone, RegExpCompileData* data,
JSRegExp::Flags flags, Handle<String> pattern,
RegExpFlags flags, Handle<String> pattern,
Handle<String> sample_subject, bool is_one_byte,
uint32_t& backtrack_limit) {
if (JSRegExp::RegistersForCaptureCount(data->capture_count) >
......@@ -1016,7 +1021,7 @@ RegExpGlobalCache::RegExpGlobalCache(Handle<JSRegExp> regexp,
regexp_(regexp),
subject_(subject),
isolate_(isolate) {
DCHECK(IsGlobal(regexp->GetFlags()));
DCHECK(IsGlobal(JSRegExp::AsRegExpFlags(regexp->GetFlags())));
switch (regexp_->TypeTag()) {
case JSRegExp::NOT_COMPILED:
......@@ -1091,7 +1096,8 @@ RegExpGlobalCache::~RegExpGlobalCache() {
}
int RegExpGlobalCache::AdvanceZeroLength(int last_index) {
if (IsUnicode(regexp_->GetFlags()) && last_index + 1 < subject_->length() &&
if (IsUnicode(JSRegExp::AsRegExpFlags(regexp_->GetFlags())) &&
last_index + 1 < subject_->length() &&
unibrow::Utf16::IsLeadSurrogate(subject_->Get(last_index)) &&
unibrow::Utf16::IsTrailSurrogate(subject_->Get(last_index + 1))) {
// Advance over the surrogate pair.
......
......@@ -5,14 +5,17 @@
#ifndef V8_REGEXP_REGEXP_H_
#define V8_REGEXP_REGEXP_H_
#include "src/objects/js-regexp.h"
#include "src/handles/handles.h"
#include "src/regexp/regexp-error.h"
#include "src/regexp/regexp-flags.h"
#include "src/zone/zone-containers.h"
namespace v8 {
namespace internal {
class JSRegExp;
class RegExpCapture;
class RegExpMatchInfo;
class RegExpNode;
class RegExpTree;
......@@ -64,9 +67,7 @@ struct RegExpCompileData {
class RegExp final : public AllStatic {
public:
// Whether the irregexp engine generates interpreter bytecode.
static bool CanGenerateBytecode() {
return FLAG_regexp_interpret_all || FLAG_regexp_tier_up;
}
static bool CanGenerateBytecode();
// Parses the RegExp pattern and prepares the JSRegExp object with
// generic data and choice of implementation - as well as what
......@@ -74,7 +75,7 @@ class RegExp final : public AllStatic {
// Returns false if compilation fails.
V8_WARN_UNUSED_RESULT static MaybeHandle<Object> Compile(
Isolate* isolate, Handle<JSRegExp> re, Handle<String> pattern,
JSRegExp::Flags flags, uint32_t backtrack_limit);
RegExpFlags flags, uint32_t backtrack_limit);
// Ensures that a regexp is fully compiled and ready to be executed on a
// subject string. Returns true on success. Return false on failure, and
......@@ -133,12 +134,9 @@ class RegExp final : public AllStatic {
Isolate* isolate, Handle<RegExpMatchInfo> last_match_info,
Handle<String> subject, int capture_count, int32_t* match);
V8_EXPORT_PRIVATE static bool CompileForTesting(Isolate* isolate, Zone* zone,
RegExpCompileData* input,
JSRegExp::Flags flags,
Handle<String> pattern,
Handle<String> sample_subject,
bool is_one_byte);
V8_EXPORT_PRIVATE static bool CompileForTesting(
Isolate* isolate, Zone* zone, RegExpCompileData* input, RegExpFlags flags,
Handle<String> pattern, Handle<String> sample_subject, bool is_one_byte);
V8_EXPORT_PRIVATE static void DotPrintForTesting(const char* label,
RegExpNode* node);
......
......@@ -546,8 +546,7 @@ static RegExpNode* Compile(const char* input, bool multiline, bool unicode,
Handle<String> sample_subject = isolate->factory()
->NewStringFromUtf8(base::CStrVector(""))
.ToHandleChecked();
RegExp::CompileForTesting(isolate, zone, &compile_data,
JSRegExp::AsJSRegExpFlags(flags), pattern,
RegExp::CompileForTesting(isolate, zone, &compile_data, flags, pattern,
sample_subject, is_one_byte);
return compile_data.node;
}
......
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