Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(454)

Unified Diff: src/builtins/builtins-regexp-gen.cc

Issue 2798933003: [regexp] Properly handle HeapNumbers in AdvanceStringIndex (Closed)
Patch Set: Rebase Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/builtins/builtins-regexp-gen.cc
diff --git a/src/builtins/builtins-regexp-gen.cc b/src/builtins/builtins-regexp-gen.cc
index d87fdf600d9f23978f1eea03b0a4fa5ba3d329d0..85452d9e98b156f9e9ac3935a98ee91d3e6a3db3 100644
--- a/src/builtins/builtins-regexp-gen.cc
+++ b/src/builtins/builtins-regexp-gen.cc
@@ -1528,20 +1528,57 @@ TF_BUILTIN(RegExpPrototypeTest, RegExpBuiltinsAssembler) {
Node* RegExpBuiltinsAssembler::AdvanceStringIndex(Node* const string,
Node* const index,
- Node* const is_unicode) {
+ Node* const is_unicode,
+ bool is_fastpath) {
+ CSA_ASSERT(this, IsHeapNumberMap(LoadReceiverMap(index)));
Camillo Bruni 2017/04/06 15:10:57 nit: add IsNumber()
jgruber 2017/04/06 16:28:33 Acknowledged - pushing to a follow-up to keep this
+ if (is_fastpath) CSA_ASSERT(this, TaggedIsSmi(index));
Camillo Bruni 2017/04/06 15:10:57 This should probably be TaggedIsPositiveSmi(index)
jgruber 2017/04/06 16:28:33 Done.
+ Variable var_index(this, MachineRepresentation::kTagged, index);
+ if (!is_fastpath) {
+ // Slow Smi normalization. Binds var_index to a Smi representation if
+ // {index} is in Smi range, and to a HeapNumber otherwise.
+ Label next(this);
+ GotoIf(TaggedIsSmi(index), &next);
+
+ CSA_ASSERT(this, IsHeapNumber(index));
+ Node* const value = LoadHeapNumberValue(index);
+ var_index.Bind(ChangeFloat64ToTagged(value));
+ Goto(&next);
Camillo Bruni 2017/04/06 15:10:58 as discussed offline: probably not worth the effor
jgruber 2017/04/06 16:28:33 Done. I'll add a corresponding assert in a follow-
+
+ Bind(&next);
+ }
+
// Default to last_index + 1.
- Node* const index_plus_one = SmiAdd(index, SmiConstant(1));
+ Node* const index_plus_one = NumberInc(var_index.value());
Variable var_result(this, MachineRepresentation::kTagged, index_plus_one);
+ // Advancing the index has some subtle issues involving the distinction
+ // between Smis and HeapNumbers. There's three cases:
+ // * {index} is a Smi, {index_plus_one} is a Smi. The standard case.
+ // * {index} is a Smi, {index_plus_one} overflows into a HeapNumber.
+ // In this case we can return the result early, because
+ // {index_plus_one} > {string}.length.
+ // * {index} is a HeapNumber, {index_plus_one} is a HeapNumber. This can only
+ // occur when {index} is outside the Smi range since we normalize
+ // explicitly. Again we can return early.
+ if (is_fastpath) {
+ // Must be in Smi range on the fast path. We control the value of {index}
+ // on all call-sites and can never exceed the length of the string.
+ STATIC_ASSERT(String::kMaxLength + 2 < Smi::kMaxValue);
+ CSA_ASSERT(this, TaggedIsSmi(index_plus_one));
Camillo Bruni 2017/04/06 15:10:57 TaggedIsPositiveSmi(index_plus_one)
jgruber 2017/04/06 16:28:34 Done.
+ }
+
Label if_isunicode(this), out(this);
- Branch(is_unicode, &if_isunicode, &out);
+ GotoIfNot(is_unicode, &out);
+
+ // Keep this unconditional (even on the fast path) just to be safe.
+ Branch(TaggedIsSmi(index_plus_one), &if_isunicode, &out);
jgruber 2017/04/06 16:28:33 Also changed this to TaggedIsPositiveSmi.
Bind(&if_isunicode);
{
Node* const string_length = LoadStringLength(string);
GotoIfNot(SmiLessThan(index_plus_one, string_length), &out);
- Node* const lead = StringCharCodeAt(string, index);
+ Node* const lead = StringCharCodeAt(string, var_index.value());
Camillo Bruni 2017/04/06 15:10:57 Please add CSA_ASSERT(this, TaggedIsPositiveSmi(in
jgruber 2017/04/06 16:28:33 Will do in a follow-up.
GotoIfNot(Word32Equal(Word32And(lead, Int32Constant(0xFC00)),
Int32Constant(0xD800)),
&out);
@@ -1552,7 +1589,7 @@ Node* RegExpBuiltinsAssembler::AdvanceStringIndex(Node* const string,
&out);
// At a surrogate pair, return index + 2.
- Node* const index_plus_two = SmiAdd(index, SmiConstant(2));
+ Node* const index_plus_two = NumberInc(index_plus_one);
var_result.Bind(index_plus_two);
Goto(&out);
@@ -1838,7 +1875,7 @@ void RegExpBuiltinsAssembler::RegExpPrototypeMatchBody(Node* const context,
}
Node* const new_last_index =
- AdvanceStringIndex(string, last_index, is_unicode);
+ AdvanceStringIndex(string, last_index, is_unicode, is_fastpath);
if (is_fastpath) {
// On the fast path, we can be certain that lastIndex can never be
@@ -2143,7 +2180,7 @@ void RegExpBuiltinsAssembler::RegExpPrototypeSplitBody(Node* const context,
Node* const is_unicode = FastFlagGetter(regexp, JSRegExp::kUnicode);
Node* const new_next_search_from =
- AdvanceStringIndex(string, next_search_from, is_unicode);
+ AdvanceStringIndex(string, next_search_from, is_unicode, true);
var_next_search_from.Bind(new_next_search_from);
Goto(&loop);

Powered by Google App Engine
This is Rietveld 408576698