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

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

Issue 2766423004: [regexp] Inline StringReplaceNonGlobalRegExpWithFunction (Closed)
Patch Set: Created 3 years, 9 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 | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/runtime/runtime-regexp.cc
diff --git a/src/runtime/runtime-regexp.cc b/src/runtime/runtime-regexp.cc
index c2271fd0ced27dd60539c3cdd2f5b93dd24dae32..b10ee3230b1671d11422f3569963c79105663181 100644
--- a/src/runtime/runtime-regexp.cc
+++ b/src/runtime/runtime-regexp.cc
@@ -1078,92 +1078,6 @@ static Object* SearchRegExpMultiple(Isolate* isolate, Handle<String> subject,
}
}
-MUST_USE_RESULT MaybeHandle<String> StringReplaceNonGlobalRegExpWithFunction(
- Isolate* isolate, Handle<String> subject, Handle<JSRegExp> regexp,
- Handle<Object> replace_obj) {
- Factory* factory = isolate->factory();
- Handle<RegExpMatchInfo> last_match_info = isolate->regexp_last_match_info();
-
- const int flags = regexp->GetFlags();
-
- DCHECK(RegExpUtils::IsUnmodifiedRegExp(isolate, regexp));
- DCHECK_EQ(flags & JSRegExp::kGlobal, 0);
-
- // TODO(jgruber): This should be an easy port to CSA with massive payback.
-
- const bool sticky = (flags & JSRegExp::kSticky) != 0;
- uint32_t last_index = 0;
- if (sticky) {
- Handle<Object> last_index_obj(regexp->LastIndex(), isolate);
- ASSIGN_RETURN_ON_EXCEPTION(isolate, last_index_obj,
- Object::ToLength(isolate, last_index_obj),
- String);
- last_index = PositiveNumberToUint32(*last_index_obj);
-
- if (static_cast<int>(last_index) > subject->length()) last_index = 0;
- }
-
- Handle<Object> match_indices_obj;
- ASSIGN_RETURN_ON_EXCEPTION(
- isolate, match_indices_obj,
- RegExpImpl::Exec(regexp, subject, last_index, last_match_info), String);
-
- if (match_indices_obj->IsNull(isolate)) {
- if (sticky) regexp->SetLastIndex(0);
- return subject;
- }
-
- Handle<RegExpMatchInfo> match_indices =
- Handle<RegExpMatchInfo>::cast(match_indices_obj);
-
- const int index = match_indices->Capture(0);
- const int end_of_match = match_indices->Capture(1);
-
- if (sticky) regexp->SetLastIndex(end_of_match);
-
- IncrementalStringBuilder builder(isolate);
- builder.AppendString(factory->NewSubString(subject, 0, index));
-
- // Compute the parameter list consisting of the match, captures, index,
- // and subject for the replace function invocation.
- // The number of captures plus one for the match.
- const int m = match_indices->NumberOfCaptureRegisters() / 2;
-
- const int argc = m + 2;
- ScopedVector<Handle<Object>> argv(argc);
-
- for (int j = 0; j < m; j++) {
- bool ok;
- Handle<String> capture =
- RegExpUtils::GenericCaptureGetter(isolate, match_indices, j, &ok);
- if (ok) {
- argv[j] = capture;
- } else {
- argv[j] = factory->undefined_value();
- }
- }
-
- argv[argc - 2] = handle(Smi::FromInt(index), isolate);
- argv[argc - 1] = subject;
-
- Handle<Object> replacement_obj;
- ASSIGN_RETURN_ON_EXCEPTION(
- isolate, replacement_obj,
- Execution::Call(isolate, replace_obj, factory->undefined_value(), argc,
- argv.start()),
- String);
-
- Handle<String> replacement;
- ASSIGN_RETURN_ON_EXCEPTION(
- isolate, replacement, Object::ToString(isolate, replacement_obj), String);
-
- builder.AppendString(replacement);
- builder.AppendString(
- factory->NewSubString(subject, end_of_match, subject->length()));
-
- return builder.Finish();
-}
-
// Legacy implementation of RegExp.prototype[Symbol.replace] which
// doesn't properly call the underlying exec method.
MUST_USE_RESULT MaybeHandle<String> RegExpReplace(Isolate* isolate,
@@ -1293,15 +1207,89 @@ RUNTIME_FUNCTION(Runtime_RegExpExecMultiple) {
RUNTIME_FUNCTION(Runtime_StringReplaceNonGlobalRegExpWithFunction) {
HandleScope scope(isolate);
DCHECK_EQ(3, args.length());
-
CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 1);
- CONVERT_ARG_HANDLE_CHECKED(JSObject, replace, 2);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, replace_obj, 2);
DCHECK(RegExpUtils::IsUnmodifiedRegExp(isolate, regexp));
- RETURN_RESULT_OR_FAILURE(isolate, StringReplaceNonGlobalRegExpWithFunction(
- isolate, subject, regexp, replace));
+ Factory* factory = isolate->factory();
+ Handle<RegExpMatchInfo> last_match_info = isolate->regexp_last_match_info();
+
+ const int flags = regexp->GetFlags();
+ DCHECK_EQ(flags & JSRegExp::kGlobal, 0);
+
+ // TODO(jgruber): This should be an easy port to CSA with massive payback.
+
+ const bool sticky = (flags & JSRegExp::kSticky) != 0;
+ uint32_t last_index = 0;
+ if (sticky) {
+ Handle<Object> last_index_obj(regexp->LastIndex(), isolate);
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, last_index_obj, Object::ToLength(isolate, last_index_obj));
+ last_index = PositiveNumberToUint32(*last_index_obj);
+
+ if (static_cast<int>(last_index) > subject->length()) last_index = 0;
+ }
+
+ Handle<Object> match_indices_obj;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, match_indices_obj,
+ RegExpImpl::Exec(regexp, subject, last_index, last_match_info));
+
+ if (match_indices_obj->IsNull(isolate)) {
+ if (sticky) regexp->SetLastIndex(0);
+ return *subject;
+ }
+
+ Handle<RegExpMatchInfo> match_indices =
+ Handle<RegExpMatchInfo>::cast(match_indices_obj);
+
+ const int index = match_indices->Capture(0);
+ const int end_of_match = match_indices->Capture(1);
+
+ if (sticky) regexp->SetLastIndex(end_of_match);
+
+ IncrementalStringBuilder builder(isolate);
+ builder.AppendString(factory->NewSubString(subject, 0, index));
+
+ // Compute the parameter list consisting of the match, captures, index,
+ // and subject for the replace function invocation.
+ // The number of captures plus one for the match.
+ const int m = match_indices->NumberOfCaptureRegisters() / 2;
+
+ const int argc = m + 2;
+ ScopedVector<Handle<Object>> argv(argc);
+
+ for (int j = 0; j < m; j++) {
+ bool ok;
+ Handle<String> capture =
+ RegExpUtils::GenericCaptureGetter(isolate, match_indices, j, &ok);
+ if (ok) {
+ argv[j] = capture;
+ } else {
+ argv[j] = factory->undefined_value();
+ }
+ }
+
+ argv[argc - 2] = handle(Smi::FromInt(index), isolate);
+ argv[argc - 1] = subject;
+
+ Handle<Object> replacement_obj;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, replacement_obj,
+ Execution::Call(isolate, replace_obj, factory->undefined_value(), argc,
+ argv.start()));
+
+ Handle<String> replacement;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, replacement, Object::ToString(isolate, replacement_obj));
+
+ builder.AppendString(replacement);
+ builder.AppendString(
+ factory->NewSubString(subject, end_of_match, subject->length()));
+
+ RETURN_RESULT_OR_FAILURE(isolate, builder.Finish());
}
namespace {
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698