summaryrefslogtreecommitdiff
path: root/deps/v8/src/regexp/regexp-parser.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/regexp/regexp-parser.cc')
-rw-r--r--deps/v8/src/regexp/regexp-parser.cc362
1 files changed, 226 insertions, 136 deletions
diff --git a/deps/v8/src/regexp/regexp-parser.cc b/deps/v8/src/regexp/regexp-parser.cc
index a7da50de20..2c6aa5b23a 100644
--- a/deps/v8/src/regexp/regexp-parser.cc
+++ b/deps/v8/src/regexp/regexp-parser.cc
@@ -16,6 +16,9 @@
#ifdef V8_INTL_SUPPORT
#include "unicode/uniset.h"
+// TODO(mathias): Remove this when we no longer need to check
+// `U_ICU_VERSION_MAJOR_NUM`.
+#include "unicode/uvernum.h"
#endif // V8_INTL_SUPPORT
namespace v8 {
@@ -26,15 +29,12 @@ RegExpParser::RegExpParser(FlatStringReader* in, Handle<String>* error,
: isolate_(isolate),
zone_(zone),
error_(error),
- captures_(NULL),
- named_captures_(NULL),
- named_back_references_(NULL),
+ captures_(nullptr),
+ named_captures_(nullptr),
+ named_back_references_(nullptr),
in_(in),
current_(kEndMarker),
- dotall_(flags & JSRegExp::kDotAll),
- ignore_case_(flags & JSRegExp::kIgnoreCase),
- multiline_(flags & JSRegExp::kMultiline),
- unicode_(flags & JSRegExp::kUnicode),
+ top_level_flags_(flags),
next_pos_(0),
captures_started_(0),
capture_count_(0),
@@ -44,7 +44,6 @@ RegExpParser::RegExpParser(FlatStringReader* in, Handle<String>* error,
is_scanned_for_captures_(false),
has_named_captures_(false),
failed_(false) {
- DCHECK_IMPLIES(dotall(), FLAG_harmony_regexp_dotall);
Advance();
}
@@ -139,7 +138,7 @@ bool RegExpParser::IsSyntaxCharacterOrSlash(uc32 c) {
RegExpTree* RegExpParser::ReportError(Vector<const char> message) {
- if (failed_) return NULL; // Do not overwrite any existing error.
+ if (failed_) return nullptr; // Do not overwrite any existing error.
failed_ = true;
*error_ = isolate()
->factory()
@@ -148,15 +147,13 @@ RegExpTree* RegExpParser::ReportError(Vector<const char> message) {
// Zip to the end to make sure the no more input is read.
current_ = kEndMarker;
next_pos_ = in()->length();
- return NULL;
+ return nullptr;
}
-
-#define CHECK_FAILED /**/); \
- if (failed_) return NULL; \
+#define CHECK_FAILED /**/); \
+ if (failed_) return nullptr; \
((void)0
-
// Pattern ::
// Disjunction
RegExpTree* RegExpParser::ParsePattern() {
@@ -184,8 +181,8 @@ RegExpTree* RegExpParser::ParsePattern() {
// Atom Quantifier
RegExpTree* RegExpParser::ParseDisjunction() {
// Used to store current state while parsing subexpressions.
- RegExpParserState initial_state(NULL, INITIAL, RegExpLookaround::LOOKAHEAD, 0,
- nullptr, ignore_case(), unicode(), zone());
+ RegExpParserState initial_state(nullptr, INITIAL, RegExpLookaround::LOOKAHEAD,
+ 0, nullptr, top_level_flags_, zone());
RegExpParserState* state = &initial_state;
// Cache the builder in a local variable for quick access.
RegExpBuilder* builder = initial_state.builder();
@@ -255,12 +252,12 @@ RegExpTree* RegExpParser::ParseDisjunction() {
return ReportError(CStrVector("Nothing to repeat"));
case '^': {
Advance();
- if (multiline()) {
- builder->AddAssertion(
- new (zone()) RegExpAssertion(RegExpAssertion::START_OF_LINE));
+ if (builder->multiline()) {
+ builder->AddAssertion(new (zone()) RegExpAssertion(
+ RegExpAssertion::START_OF_LINE, builder->flags()));
} else {
- builder->AddAssertion(
- new (zone()) RegExpAssertion(RegExpAssertion::START_OF_INPUT));
+ builder->AddAssertion(new (zone()) RegExpAssertion(
+ RegExpAssertion::START_OF_INPUT, builder->flags()));
set_contains_anchor();
}
continue;
@@ -268,9 +265,10 @@ RegExpTree* RegExpParser::ParseDisjunction() {
case '$': {
Advance();
RegExpAssertion::AssertionType assertion_type =
- multiline() ? RegExpAssertion::END_OF_LINE
- : RegExpAssertion::END_OF_INPUT;
- builder->AddAssertion(new (zone()) RegExpAssertion(assertion_type));
+ builder->multiline() ? RegExpAssertion::END_OF_LINE
+ : RegExpAssertion::END_OF_INPUT;
+ builder->AddAssertion(
+ new (zone()) RegExpAssertion(assertion_type, builder->flags()));
continue;
}
case '.': {
@@ -278,87 +276,26 @@ RegExpTree* RegExpParser::ParseDisjunction() {
ZoneList<CharacterRange>* ranges =
new (zone()) ZoneList<CharacterRange>(2, zone());
- if (dotall()) {
+ if (builder->dotall()) {
// Everything.
- DCHECK(FLAG_harmony_regexp_dotall);
CharacterRange::AddClassEscape('*', ranges, false, zone());
} else {
// Everything except \x0a, \x0d, \u2028 and \u2029
CharacterRange::AddClassEscape('.', ranges, false, zone());
}
- RegExpCharacterClass* cc = new (zone()) RegExpCharacterClass(ranges);
+ RegExpCharacterClass* cc =
+ new (zone()) RegExpCharacterClass(ranges, builder->flags());
builder->AddCharacterClass(cc);
break;
}
case '(': {
- SubexpressionType subexpr_type = CAPTURE;
- RegExpLookaround::Type lookaround_type = state->lookaround_type();
- bool is_named_capture = false;
- Advance();
- if (current() == '?') {
- switch (Next()) {
- case ':':
- subexpr_type = GROUPING;
- Advance(2);
- break;
- case '=':
- lookaround_type = RegExpLookaround::LOOKAHEAD;
- subexpr_type = POSITIVE_LOOKAROUND;
- Advance(2);
- break;
- case '!':
- lookaround_type = RegExpLookaround::LOOKAHEAD;
- subexpr_type = NEGATIVE_LOOKAROUND;
- Advance(2);
- break;
- case '<':
- Advance();
- if (FLAG_harmony_regexp_lookbehind) {
- if (Next() == '=') {
- subexpr_type = POSITIVE_LOOKAROUND;
- lookaround_type = RegExpLookaround::LOOKBEHIND;
- Advance(2);
- break;
- } else if (Next() == '!') {
- subexpr_type = NEGATIVE_LOOKAROUND;
- lookaround_type = RegExpLookaround::LOOKBEHIND;
- Advance(2);
- break;
- }
- }
- if (FLAG_harmony_regexp_named_captures) {
- has_named_captures_ = true;
- is_named_capture = true;
- Advance();
- break;
- }
- // Fall through.
- default:
- return ReportError(CStrVector("Invalid group"));
- }
- }
-
- const ZoneVector<uc16>* capture_name = nullptr;
- if (subexpr_type == CAPTURE) {
- if (captures_started_ >= kMaxCaptures) {
- return ReportError(CStrVector("Too many captures"));
- }
- captures_started_++;
-
- if (is_named_capture) {
- capture_name = ParseCaptureGroupName(CHECK_FAILED);
- }
- }
- // Store current state and begin new disjunction parsing.
- state = new (zone()) RegExpParserState(
- state, subexpr_type, lookaround_type, captures_started_,
- capture_name, ignore_case(), unicode(), zone());
+ state = ParseOpenParenthesis(state CHECK_FAILED);
builder = state->builder();
continue;
}
case '[': {
- RegExpTree* cc = ParseCharacterClass(CHECK_FAILED);
+ RegExpTree* cc = ParseCharacterClass(builder CHECK_FAILED);
builder->AddCharacterClass(cc->AsCharacterClass());
break;
}
@@ -370,13 +307,13 @@ RegExpTree* RegExpParser::ParseDisjunction() {
return ReportError(CStrVector("\\ at end of pattern"));
case 'b':
Advance(2);
- builder->AddAssertion(
- new (zone()) RegExpAssertion(RegExpAssertion::BOUNDARY));
+ builder->AddAssertion(new (zone()) RegExpAssertion(
+ RegExpAssertion::BOUNDARY, builder->flags()));
continue;
case 'B':
Advance(2);
- builder->AddAssertion(
- new (zone()) RegExpAssertion(RegExpAssertion::NON_BOUNDARY));
+ builder->AddAssertion(new (zone()) RegExpAssertion(
+ RegExpAssertion::NON_BOUNDARY, builder->flags()));
continue;
// AtomEscape ::
// CharacterClassEscape
@@ -393,10 +330,10 @@ RegExpTree* RegExpParser::ParseDisjunction() {
Advance(2);
ZoneList<CharacterRange>* ranges =
new (zone()) ZoneList<CharacterRange>(2, zone());
- CharacterRange::AddClassEscape(c, ranges,
- unicode() && ignore_case(), zone());
+ CharacterRange::AddClassEscape(
+ c, ranges, unicode() && builder->ignore_case(), zone());
RegExpCharacterClass* cc =
- new (zone()) RegExpCharacterClass(ranges);
+ new (zone()) RegExpCharacterClass(ranges, builder->flags());
builder->AddCharacterClass(cc);
break;
}
@@ -412,7 +349,7 @@ RegExpTree* RegExpParser::ParseDisjunction() {
return ReportError(CStrVector("Invalid property name"));
}
RegExpCharacterClass* cc =
- new (zone()) RegExpCharacterClass(ranges);
+ new (zone()) RegExpCharacterClass(ranges, builder->flags());
builder->AddCharacterClass(cc);
} else {
// With /u, no identity escapes except for syntax characters
@@ -445,7 +382,8 @@ RegExpTree* RegExpParser::ParseDisjunction() {
builder->AddEmpty();
} else {
RegExpCapture* capture = GetCapture(index);
- RegExpTree* atom = new (zone()) RegExpBackReference(capture);
+ RegExpTree* atom =
+ new (zone()) RegExpBackReference(capture, builder->flags());
builder->AddAtom(atom);
}
break;
@@ -640,6 +578,135 @@ RegExpTree* RegExpParser::ParseDisjunction() {
}
}
+RegExpParser::RegExpParserState* RegExpParser::ParseOpenParenthesis(
+ RegExpParserState* state) {
+ RegExpLookaround::Type lookaround_type = state->lookaround_type();
+ bool is_named_capture = false;
+ JSRegExp::Flags switch_on = JSRegExp::kNone;
+ JSRegExp::Flags switch_off = JSRegExp::kNone;
+ const ZoneVector<uc16>* capture_name = nullptr;
+ SubexpressionType subexpr_type = CAPTURE;
+ Advance();
+ if (current() == '?') {
+ switch (Next()) {
+ case ':':
+ Advance(2);
+ subexpr_type = GROUPING;
+ break;
+ case '=':
+ Advance(2);
+ lookaround_type = RegExpLookaround::LOOKAHEAD;
+ subexpr_type = POSITIVE_LOOKAROUND;
+ break;
+ case '!':
+ Advance(2);
+ lookaround_type = RegExpLookaround::LOOKAHEAD;
+ subexpr_type = NEGATIVE_LOOKAROUND;
+ break;
+ case '-':
+ case 'i':
+ case 's':
+ case 'm': {
+ if (!FLAG_regexp_mode_modifiers) {
+ ReportError(CStrVector("Invalid group"));
+ return nullptr;
+ }
+ Advance();
+ bool flags_sense = true; // Switching on flags.
+ while (subexpr_type != GROUPING) {
+ switch (current()) {
+ case '-':
+ if (!flags_sense) {
+ ReportError(CStrVector("Multiple dashes in flag group"));
+ return nullptr;
+ }
+ flags_sense = false;
+ Advance();
+ continue;
+ case 's':
+ case 'i':
+ case 'm': {
+ JSRegExp::Flags bit = JSRegExp::kUnicode;
+ if (current() == 'i') bit = JSRegExp::kIgnoreCase;
+ if (current() == 'm') bit = JSRegExp::kMultiline;
+ if (current() == 's') bit = JSRegExp::kDotAll;
+ if (((switch_on | switch_off) & bit) != 0) {
+ ReportError(CStrVector("Repeated flag in flag group"));
+ return nullptr;
+ }
+ if (flags_sense) {
+ switch_on |= bit;
+ } else {
+ switch_off |= bit;
+ }
+ Advance();
+ continue;
+ }
+ case ')': {
+ Advance();
+ state->builder()
+ ->FlushText(); // Flush pending text using old flags.
+ // These (?i)-style flag switches don't put us in a subexpression
+ // at all, they just modify the flags in the rest of the current
+ // subexpression.
+ JSRegExp::Flags flags =
+ (state->builder()->flags() | switch_on) & ~switch_off;
+ state->builder()->set_flags(flags);
+ return state;
+ }
+ case ':':
+ Advance();
+ subexpr_type = GROUPING; // Will break us out of the outer loop.
+ continue;
+ default:
+ ReportError(CStrVector("Invalid flag group"));
+ return nullptr;
+ }
+ }
+ break;
+ }
+ case '<':
+ Advance();
+ if (Next() == '=') {
+ Advance(2);
+ lookaround_type = RegExpLookaround::LOOKBEHIND;
+ subexpr_type = POSITIVE_LOOKAROUND;
+ break;
+ } else if (Next() == '!') {
+ Advance(2);
+ lookaround_type = RegExpLookaround::LOOKBEHIND;
+ subexpr_type = NEGATIVE_LOOKAROUND;
+ break;
+ }
+ if (FLAG_harmony_regexp_named_captures) {
+ is_named_capture = true;
+ has_named_captures_ = true;
+ Advance();
+ break;
+ }
+ // Fall through.
+ default:
+ ReportError(CStrVector("Invalid group"));
+ return nullptr;
+ }
+ }
+ if (subexpr_type == CAPTURE) {
+ if (captures_started_ >= kMaxCaptures) {
+ ReportError(CStrVector("Too many captures"));
+ return nullptr;
+ }
+ captures_started_++;
+
+ if (is_named_capture) {
+ capture_name = ParseCaptureGroupName(CHECK_FAILED);
+ }
+ }
+ JSRegExp::Flags flags = (state->builder()->flags() | switch_on) & ~switch_off;
+ // Store current state and begin new disjunction parsing.
+ return new (zone())
+ RegExpParserState(state, subexpr_type, lookaround_type, captures_started_,
+ capture_name, flags, zone());
+}
#ifdef DEBUG
// Currently only used in an DCHECK.
@@ -703,10 +770,8 @@ void RegExpParser::ScanForCaptures() {
Advance();
if (current() != '<') break;
- if (FLAG_harmony_regexp_lookbehind) {
- Advance();
- if (current() == '=' || current() == '!') break;
- }
+ Advance();
+ if (current() == '=' || current() == '!') break;
// Found a possible named capture. It could turn out to be a syntax
// error (e.g. an unterminated or invalid name), but that distinction
@@ -857,7 +922,8 @@ bool RegExpParser::ParseNamedBackReference(RegExpBuilder* builder,
if (state->IsInsideCaptureGroup(name)) {
builder->AddEmpty();
} else {
- RegExpBackReference* atom = new (zone()) RegExpBackReference();
+ RegExpBackReference* atom =
+ new (zone()) RegExpBackReference(builder->flags());
atom->set_name(name);
builder->AddAtom(atom);
@@ -909,7 +975,7 @@ RegExpCapture* RegExpParser::GetCapture(int index) {
int know_captures =
is_scanned_for_captures_ ? capture_count_ : captures_started_;
DCHECK(index <= know_captures);
- if (captures_ == NULL) {
+ if (captures_ == nullptr) {
captures_ = new (zone()) ZoneList<RegExpCapture*>(know_captures, zone());
}
while (captures_->length() < know_captures) {
@@ -948,7 +1014,7 @@ bool RegExpParser::HasNamedCaptures() {
}
bool RegExpParser::RegExpParserState::IsInsideCaptureGroup(int index) {
- for (RegExpParserState* s = this; s != NULL; s = s->previous_state()) {
+ for (RegExpParserState* s = this; s != nullptr; s = s->previous_state()) {
if (s->group_type() != CAPTURE) continue;
// Return true if we found the matching capture index.
if (index == s->capture_index()) return true;
@@ -961,7 +1027,7 @@ bool RegExpParser::RegExpParserState::IsInsideCaptureGroup(int index) {
bool RegExpParser::RegExpParserState::IsInsideCaptureGroup(
const ZoneVector<uc16>* name) {
DCHECK_NOT_NULL(name);
- for (RegExpParserState* s = this; s != NULL; s = s->previous_state()) {
+ for (RegExpParserState* s = this; s != nullptr; s = s->previous_state()) {
if (s->capture_name() == nullptr) continue;
if (*s->capture_name() == *name) return true;
}
@@ -1115,11 +1181,12 @@ namespace {
bool IsExactPropertyAlias(const char* property_name, UProperty property) {
const char* short_name = u_getPropertyName(property, U_SHORT_PROPERTY_NAME);
- if (short_name != NULL && strcmp(property_name, short_name) == 0) return true;
+ if (short_name != nullptr && strcmp(property_name, short_name) == 0)
+ return true;
for (int i = 0;; i++) {
const char* long_name = u_getPropertyName(
property, static_cast<UPropertyNameChoice>(U_LONG_PROPERTY_NAME + i));
- if (long_name == NULL) break;
+ if (long_name == nullptr) break;
if (strcmp(property_name, long_name) == 0) return true;
}
return false;
@@ -1129,14 +1196,14 @@ bool IsExactPropertyValueAlias(const char* property_value_name,
UProperty property, int32_t property_value) {
const char* short_name =
u_getPropertyValueName(property, property_value, U_SHORT_PROPERTY_NAME);
- if (short_name != NULL && strcmp(property_value_name, short_name) == 0) {
+ if (short_name != nullptr && strcmp(property_value_name, short_name) == 0) {
return true;
}
for (int i = 0;; i++) {
const char* long_name = u_getPropertyValueName(
property, property_value,
static_cast<UPropertyNameChoice>(U_LONG_PROPERTY_NAME + i));
- if (long_name == NULL) break;
+ if (long_name == nullptr) break;
if (strcmp(property_value_name, long_name) == 0) return true;
}
return false;
@@ -1226,9 +1293,9 @@ bool IsSupportedBinaryProperty(UProperty property) {
case UCHAR_DEPRECATED:
case UCHAR_DIACRITIC:
case UCHAR_EMOJI:
- // TODO(yangguo): Uncomment this once we upgrade to ICU 60.
- // See https://ssl.icu-project.org/trac/ticket/13062
- // case UCHAR_EMOJI_COMPONENT:
+#if U_ICU_VERSION_MAJOR_NUM >= 60
+ case UCHAR_EMOJI_COMPONENT:
+#endif
case UCHAR_EMOJI_MODIFIER_BASE:
case UCHAR_EMOJI_MODIFIER:
case UCHAR_EMOJI_PRESENTATION:
@@ -1250,6 +1317,9 @@ bool IsSupportedBinaryProperty(UProperty property) {
case UCHAR_PATTERN_WHITE_SPACE:
case UCHAR_QUOTATION_MARK:
case UCHAR_RADICAL:
+#if U_ICU_VERSION_MAJOR_NUM >= 60
+ case UCHAR_REGIONAL_INDICATOR:
+#endif
case UCHAR_S_TERM:
case UCHAR_SOFT_DOTTED:
case UCHAR_TERMINAL_PUNCTUATION:
@@ -1266,6 +1336,19 @@ bool IsSupportedBinaryProperty(UProperty property) {
return false;
}
+bool IsUnicodePropertyValueCharacter(char c) {
+ // https://tc39.github.io/proposal-regexp-unicode-property-escapes/
+ //
+ // Note that using this to validate each parsed char is quite conservative.
+ // A possible alternative solution would be to only ensure the parsed
+ // property name/value candidate string does not contain '\0' characters and
+ // let ICU lookups trigger the final failure.
+ if ('a' <= c && c <= 'z') return true;
+ if ('A' <= c && c <= 'Z') return true;
+ if ('0' <= c && c <= '9') return true;
+ return (c == '_');
+}
+
} // anonymous namespace
bool RegExpParser::ParsePropertyClass(ZoneList<CharacterRange>* result,
@@ -1283,11 +1366,13 @@ bool RegExpParser::ParsePropertyClass(ZoneList<CharacterRange>* result,
if (current() == '{') {
// Parse \p{[PropertyName=]PropertyNameValue}
for (Advance(); current() != '}' && current() != '='; Advance()) {
+ if (!IsUnicodePropertyValueCharacter(current())) return false;
if (!has_next()) return false;
first_part.push_back(static_cast<char>(current()));
}
if (current() == '=') {
for (Advance(); current() != '}'; Advance()) {
+ if (!IsUnicodePropertyValueCharacter(current())) return false;
if (!has_next()) return false;
second_part.push_back(static_cast<char>(current()));
}
@@ -1299,6 +1384,10 @@ bool RegExpParser::ParsePropertyClass(ZoneList<CharacterRange>* result,
Advance();
first_part.push_back(0); // null-terminate string.
+ DCHECK(first_part.size() - 1 == std::strlen(first_part.data()));
+ DCHECK(second_part.empty() ||
+ second_part.size() - 1 == std::strlen(second_part.data()));
+
if (second_part.empty()) {
// First attempt to interpret as general category property value name.
const char* name = first_part.data();
@@ -1526,7 +1615,7 @@ void RegExpParser::ParseClassEscape(ZoneList<CharacterRange>* ranges,
}
}
-RegExpTree* RegExpParser::ParseCharacterClass() {
+RegExpTree* RegExpParser::ParseCharacterClass(const RegExpBuilder* builder) {
static const char* kUnterminated = "Unterminated character class";
static const char* kRangeInvalid = "Invalid character class";
static const char* kRangeOutOfOrder = "Range out of order in character class";
@@ -1540,7 +1629,7 @@ RegExpTree* RegExpParser::ParseCharacterClass() {
}
ZoneList<CharacterRange>* ranges =
new (zone()) ZoneList<CharacterRange>(2, zone());
- bool add_unicode_case_equivalents = unicode() && ignore_case();
+ bool add_unicode_case_equivalents = unicode() && builder->ignore_case();
while (has_more() && current() != ']') {
uc32 char_1, char_2;
bool is_class_1, is_class_2;
@@ -1587,9 +1676,10 @@ RegExpTree* RegExpParser::ParseCharacterClass() {
ranges->Add(CharacterRange::Everything(), zone());
is_negated = !is_negated;
}
- RegExpCharacterClass::Flags flags;
- if (is_negated) flags = RegExpCharacterClass::NEGATED;
- return new (zone()) RegExpCharacterClass(ranges, flags);
+ RegExpCharacterClass::CharacterClassFlags character_class_flags;
+ if (is_negated) character_class_flags = RegExpCharacterClass::NEGATED;
+ return new (zone())
+ RegExpCharacterClass(ranges, builder->flags(), character_class_flags);
}
@@ -1599,14 +1689,14 @@ RegExpTree* RegExpParser::ParseCharacterClass() {
bool RegExpParser::ParseRegExp(Isolate* isolate, Zone* zone,
FlatStringReader* input, JSRegExp::Flags flags,
RegExpCompileData* result) {
- DCHECK(result != NULL);
+ DCHECK(result != nullptr);
RegExpParser parser(input, &result->error, flags, isolate, zone);
RegExpTree* tree = parser.ParsePattern();
if (parser.failed()) {
- DCHECK(tree == NULL);
+ DCHECK(tree == nullptr);
DCHECK(!result->error.is_null());
} else {
- DCHECK(tree != NULL);
+ DCHECK(tree != nullptr);
DCHECK(result->error.is_null());
if (FLAG_trace_regexp_parser) {
OFStream os(stdout);
@@ -1623,12 +1713,11 @@ bool RegExpParser::ParseRegExp(Isolate* isolate, Zone* zone,
return !parser.failed();
}
-RegExpBuilder::RegExpBuilder(Zone* zone, bool ignore_case, bool unicode)
+RegExpBuilder::RegExpBuilder(Zone* zone, JSRegExp::Flags flags)
: zone_(zone),
pending_empty_(false),
- ignore_case_(ignore_case),
- unicode_(unicode),
- characters_(NULL),
+ flags_(flags),
+ characters_(nullptr),
pending_surrogate_(kNoPendingSurrogate),
terms_(),
alternatives_()
@@ -1663,7 +1752,7 @@ void RegExpBuilder::AddTrailSurrogate(uc16 trail_surrogate) {
surrogate_pair.Add(lead_surrogate, zone());
surrogate_pair.Add(trail_surrogate, zone());
RegExpAtom* atom =
- new (zone()) RegExpAtom(surrogate_pair.ToConstVector());
+ new (zone()) RegExpAtom(surrogate_pair.ToConstVector(), flags_);
AddAtom(atom);
}
} else {
@@ -1686,9 +1775,10 @@ void RegExpBuilder::FlushPendingSurrogate() {
void RegExpBuilder::FlushCharacters() {
FlushPendingSurrogate();
pending_empty_ = false;
- if (characters_ != NULL) {
- RegExpTree* atom = new (zone()) RegExpAtom(characters_->ToConstVector());
- characters_ = NULL;
+ if (characters_ != nullptr) {
+ RegExpTree* atom =
+ new (zone()) RegExpAtom(characters_->ToConstVector(), flags_);
+ characters_ = nullptr;
text_.Add(atom, zone());
LAST(ADD_ATOM);
}
@@ -1717,7 +1807,7 @@ void RegExpBuilder::AddCharacter(uc16 c) {
if (NeedsDesugaringForIgnoreCase(c)) {
AddCharacterClassForDesugaring(c);
} else {
- if (characters_ == NULL) {
+ if (characters_ == nullptr) {
characters_ = new (zone()) ZoneList<uc16>(4, zone());
}
characters_->Add(c, zone());
@@ -1763,7 +1853,7 @@ void RegExpBuilder::AddCharacterClass(RegExpCharacterClass* cc) {
void RegExpBuilder::AddCharacterClassForDesugaring(uc32 c) {
AddTerm(new (zone()) RegExpCharacterClass(
- CharacterRange::List(zone(), CharacterRange::Singleton(c))));
+ CharacterRange::List(zone(), CharacterRange::Singleton(c)), flags_));
}
@@ -1874,18 +1964,18 @@ bool RegExpBuilder::AddQuantifierToAtom(
return true;
}
RegExpTree* atom;
- if (characters_ != NULL) {
+ if (characters_ != nullptr) {
DCHECK(last_added_ == ADD_CHAR);
// Last atom was character.
Vector<const uc16> char_vector = characters_->ToConstVector();
int num_chars = char_vector.length();
if (num_chars > 1) {
Vector<const uc16> prefix = char_vector.SubVector(0, num_chars - 1);
- text_.Add(new (zone()) RegExpAtom(prefix), zone());
+ text_.Add(new (zone()) RegExpAtom(prefix, flags_), zone());
char_vector = char_vector.SubVector(num_chars - 1, num_chars);
}
- characters_ = NULL;
- atom = new (zone()) RegExpAtom(char_vector);
+ characters_ = nullptr;
+ atom = new (zone()) RegExpAtom(char_vector, flags_);
FlushText();
} else if (text_.length() > 0) {
DCHECK(last_added_ == ADD_ATOM);