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

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

Issue 2630233003: [regexp] Create property on result for each named capture (Closed)
Patch Set: Blacklist index, input, length Created 3 years, 11 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
« no previous file with comments | « no previous file | src/objects.h » ('j') | src/regexp/regexp-parser.cc » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/builtins/builtins-regexp.cc
diff --git a/src/builtins/builtins-regexp.cc b/src/builtins/builtins-regexp.cc
index 2191268441c92687715ff86cbfecd9774b770ebc..229cd5d3d84931f0507f531fa900831db9a14558 100644
--- a/src/builtins/builtins-regexp.cc
+++ b/src/builtins/builtins-regexp.cc
@@ -33,8 +33,9 @@ class RegExpBuiltinsAssembler : public CodeStubAssembler {
void StoreLastIndex(Node* context, Node* regexp, Node* value,
bool is_fastpath);
- Node* ConstructNewResultFromMatchInfo(Node* context, Node* match_info,
- Node* string);
+ Node* ConstructNewResultFromMatchInfo(Node* const context, Node* const regexp,
+ Node* const match_info,
+ Node* const string);
Node* RegExpPrototypeExecBodyWithoutResult(Node* const context,
Node* const regexp,
@@ -141,10 +142,10 @@ void RegExpBuiltinsAssembler::StoreLastIndex(Node* context, Node* regexp,
}
}
-Node* RegExpBuiltinsAssembler::ConstructNewResultFromMatchInfo(Node* context,
- Node* match_info,
- Node* string) {
- Label out(this);
+Node* RegExpBuiltinsAssembler::ConstructNewResultFromMatchInfo(
+ Node* const context, Node* const regexp, Node* const match_info,
+ Node* const string) {
+ Label named_captures(this), out(this);
Node* const num_indices = SmiUntag(LoadFixedArrayElement(
match_info, RegExpMatchInfo::kNumberOfCapturesIndex));
@@ -164,7 +165,7 @@ Node* RegExpBuiltinsAssembler::ConstructNewResultFromMatchInfo(Node* context,
StoreFixedArrayElement(result_elements, 0, first, SKIP_WRITE_BARRIER);
- GotoIf(SmiEqual(num_results, SmiConstant(Smi::FromInt(1))), &out);
+ GotoIf(SmiEqual(num_results, SmiConstant(1)), &named_captures);
// Store all remaining captures.
Node* const limit = IntPtrAdd(
@@ -187,7 +188,7 @@ Node* RegExpBuiltinsAssembler::ConstructNewResultFromMatchInfo(Node* context,
Node* const start = LoadFixedArrayElement(match_info, from_cursor);
Label next_iter(this);
- GotoIf(SmiEqual(start, SmiConstant(Smi::FromInt(-1))), &next_iter);
+ GotoIf(SmiEqual(start, SmiConstant(-1)), &next_iter);
Node* const from_cursor_plus1 = IntPtrAdd(from_cursor, IntPtrConstant(1));
Node* const end = LoadFixedArrayElement(match_info, from_cursor_plus1);
@@ -199,7 +200,60 @@ Node* RegExpBuiltinsAssembler::ConstructNewResultFromMatchInfo(Node* context,
Bind(&next_iter);
var_from_cursor.Bind(IntPtrAdd(from_cursor, IntPtrConstant(2)));
var_to_cursor.Bind(IntPtrAdd(to_cursor, IntPtrConstant(1)));
- Branch(UintPtrLessThan(var_from_cursor.value(), limit), &loop, &out);
+ Branch(UintPtrLessThan(var_from_cursor.value(), limit), &loop,
+ &named_captures);
+ }
+
+ Bind(&named_captures);
+ {
+ // Preparations for named capture properties. Exit early if the result is
+ // either not an IRREGEXP or does not have any named captures to minimize
+ // performance impact.
+
+ CSA_ASSERT(this, HasInstanceType(regexp, JS_REGEXP_TYPE));
+ Node* const data = LoadObjectField(regexp, JSRegExp::kDataOffset);
jgruber 2017/01/17 09:26:51 This unconditionally adds two loads and two branch
Yang 2017/01/18 13:25:36 I think we can already make this a bit simpler: we
jgruber 2017/01/19 15:59:12 Very good point, done.
+ Node* const tag = LoadFixedArrayElement(data, JSRegExp::kTagIndex);
+ GotoUnless(SmiEqual(tag, SmiConstant(JSRegExp::IRREGEXP)), &out);
+
+ // The names fixed array associates names at even indices with a capture
+ // index at odd indices.
+ Node* const names =
+ LoadFixedArrayElement(data, JSRegExp::kIrregexpCaptureNameMapIndex);
+ GotoIf(SmiEqual(names, SmiConstant(0)), &out);
+
+ // One or more named captures exist, add a property for each one.
+
+ CSA_ASSERT(this, HasInstanceType(names, FIXED_ARRAY_TYPE));
+ Node* const names_length = LoadAndUntagFixedArrayBaseLength(names);
+ CSA_ASSERT(this, IntPtrGreaterThan(names_length, IntPtrConstant(0)));
+
+ Variable var_i(this, MachineType::PointerRepresentation());
+ var_i.Bind(IntPtrConstant(0));
+
+ Variable* vars[] = {&var_i};
+ const int vars_count = sizeof(vars) / sizeof(vars[0]);
+ Label loop(this, vars_count, vars);
+
+ Goto(&loop);
+ Bind(&loop);
+ {
+ Node* const i = var_i.value();
+ Node* const i_plus_1 = IntPtrAdd(i, IntPtrConstant(1));
+ Node* const i_plus_2 = IntPtrAdd(i_plus_1, IntPtrConstant(1));
+
+ Node* const name = LoadFixedArrayElement(names, i);
+ Node* const index = LoadFixedArrayElement(names, i_plus_1);
+ Node* const capture =
+ LoadFixedArrayElement(result_elements, SmiUntag(index));
+
+ Node* const language_mode = SmiConstant(Smi::FromInt(STRICT));
+ CallRuntime(Runtime::kSetProperty, context, result, name, capture,
+ language_mode);
+
+ var_i.Bind(i_plus_2);
+ Branch(IntPtrGreaterThanOrEqual(var_i.value(), names_length), &out,
+ &loop);
+ }
}
Bind(&out);
@@ -352,7 +406,7 @@ Node* RegExpBuiltinsAssembler::RegExpPrototypeExecBody(Node* const context,
{
Node* const match_indices = indices_or_null;
Node* const result =
- ConstructNewResultFromMatchInfo(context, match_indices, string);
+ ConstructNewResultFromMatchInfo(context, regexp, match_indices, string);
var_result.Bind(result);
Goto(&out);
}
@@ -2522,7 +2576,7 @@ TF_BUILTIN(RegExpInternalMatch, RegExpBuiltinsAssembler) {
Bind(&if_matched);
{
Node* result =
- ConstructNewResultFromMatchInfo(context, match_indices, string);
+ ConstructNewResultFromMatchInfo(context, regexp, match_indices, string);
Return(result);
}
}
« no previous file with comments | « no previous file | src/objects.h » ('j') | src/regexp/regexp-parser.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698