[regexp] Don't recognize the 'l' flag unless enabled

.. by the runtime flag --enable-experimental-regexp-engine.

Introduced in https://chromium-review.googlesource.com/c/v8/v8/+/2461244

Tbr: neis@chromium.org
Bug: v8:10765
Change-Id: Ic32464ced7e5ddb4c31fe165eddb6b9d19260efc
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2516920
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: Georg Neis <neis@chromium.org>
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Auto-Submit: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#70963}
This commit is contained in:
Jakob Gruber 2020-11-03 14:50:10 +01:00 committed by Commit Bot
parent 1ef2936adf
commit 0593cb7218
4 changed files with 51 additions and 4 deletions

View File

@ -957,12 +957,37 @@ TNode<String> RegExpBuiltinsAssembler::FlagsGetter(TNode<Context> context,
CASE_FOR_FLAG("global", JSRegExp::kGlobal);
CASE_FOR_FLAG("ignoreCase", JSRegExp::kIgnoreCase);
CASE_FOR_FLAG("linear", JSRegExp::kLinear);
CASE_FOR_FLAG("multiline", JSRegExp::kMultiline);
CASE_FOR_FLAG("dotAll", JSRegExp::kDotAll);
CASE_FOR_FLAG("unicode", JSRegExp::kUnicode);
CASE_FOR_FLAG("sticky", JSRegExp::kSticky);
#undef CASE_FOR_FLAG
{
Label next(this);
// Check the runtime value of FLAG_enable_experimental_regexp_engine
// first.
TNode<Word32T> flag_value = UncheckedCast<Word32T>(
Load(MachineType::Uint8(),
ExternalConstant(
ExternalReference::
address_of_enable_experimental_regexp_engine())));
GotoIf(Word32Equal(Word32And(flag_value, Int32Constant(0xFF)),
Int32Constant(0)),
&next);
const TNode<Object> flag = GetProperty(
context, regexp, isolate->factory()->InternalizeUtf8String("linear"));
Label if_isflagset(this);
BranchIfToBooleanIsTrue(flag, &if_isflagset, &next);
BIND(&if_isflagset);
var_length = Uint32Add(var_length.value(), Uint32Constant(1));
var_flags =
Signed(WordOr(var_flags.value(), IntPtrConstant(JSRegExp::kLinear)));
Goto(&next);
BIND(&next);
}
}
// Allocate a string of the required length and fill it with the corresponding
@ -1204,9 +1229,20 @@ TNode<BoolT> RegExpBuiltinsAssembler::FastFlagGetter(TNode<JSRegExp> regexp,
TNode<BoolT> RegExpBuiltinsAssembler::SlowFlagGetter(TNode<Context> context,
TNode<Object> regexp,
JSRegExp::Flag flag) {
Label out(this);
Label out(this), if_true(this), if_false(this);
TVARIABLE(BoolT, var_result);
// Only enabled based on a runtime flag.
if (flag == JSRegExp::kLinear) {
TNode<Word32T> flag_value = UncheckedCast<Word32T>(Load(
MachineType::Uint8(),
ExternalConstant(ExternalReference::
address_of_enable_experimental_regexp_engine())));
GotoIf(Word32Equal(Word32And(flag_value, Int32Constant(0xFF)),
Int32Constant(0)),
&if_false);
}
Handle<String> name;
switch (flag) {
case JSRegExp::kNone:
@ -1235,8 +1271,6 @@ TNode<BoolT> RegExpBuiltinsAssembler::SlowFlagGetter(TNode<Context> context,
}
TNode<Object> value = GetProperty(context, regexp, name);
Label if_true(this), if_false(this);
BranchIfToBooleanIsTrue(value, &if_true, &if_false);
BIND(&if_true);

View File

@ -475,6 +475,11 @@ ExternalReference ExternalReference::address_of_double_neg_constant() {
return ExternalReference(reinterpret_cast<Address>(&double_negate_constant));
}
ExternalReference
ExternalReference::address_of_enable_experimental_regexp_engine() {
return ExternalReference(&FLAG_enable_experimental_regexp_engine);
}
ExternalReference ExternalReference::is_profiling_address(Isolate* isolate) {
return ExternalReference(isolate->is_profiling_address());
}

View File

@ -100,6 +100,8 @@ class StatsCounter;
V(abort_with_reason, "abort_with_reason") \
V(address_of_double_abs_constant, "double_absolute_constant") \
V(address_of_double_neg_constant, "double_negate_constant") \
V(address_of_enable_experimental_regexp_engine, \
"address_of_enable_experimental_regexp_engine") \
V(address_of_float_abs_constant, "float_absolute_constant") \
V(address_of_float_neg_constant, "float_negate_constant") \
V(address_of_min_int, "LDoubleConstant::min_int") \

View File

@ -14,3 +14,9 @@ assertThrows(() => new RegExp("((a*)*)*\1", "l"), SyntaxError)
// RegExps shouldn't have a 'linear' property.
assertFalse(RegExp.prototype.hasOwnProperty('linear'));
assertFalse(/123/.hasOwnProperty('linear'));
{
let re = /./;
re.linear = true;
assertEquals("", re.flags);
}