diff options
author | Rubin Xu <rubinxu@google.com> | 2020-03-05 15:14:38 +0000 |
---|---|---|
committer | Bryan Ferris <bferris@google.com> | 2020-03-23 18:05:01 +0000 |
commit | df2d4b58f6fa0d0f0c563eac34d0bea2768d9bec (patch) | |
tree | b2e720fde07e2846ed1a78453ef53caa0222845c /src | |
parent | 30bef65ab3c379c3712170ef97b6aa3280882b88 (diff) | |
download | v8-df2d4b58f6fa0d0f0c563eac34d0bea2768d9bec.tar.gz |
Cherry-pick "Refactor Regexp.prototype"
Original change: https://chromium-review.googlesource.com/c/v8/v8/+/1547660
Bug: 147664838
Test: pacrunner32 test.pac
Test: gts-tradefed run gts-dev --module GtsGmscoreHostTestCases --test com.google.android.gts.devicepolicy.DeviceOwnerTest#testProxyPacProxyTest
Change-Id: Iac9370d48ca0ed84d5903ab0469c0ae01d62a621
Merged-In: Iac9370d48ca0ed84d5903ab0469c0ae01d62a621
Diffstat (limited to 'src')
-rw-r--r-- | src/regexp/regexp-utils.cc | 10 | ||||
-rw-r--r-- | src/runtime/runtime-regexp.cc | 42 |
2 files changed, 29 insertions, 23 deletions
diff --git a/src/regexp/regexp-utils.cc b/src/regexp/regexp-utils.cc index c787a502..8d4b1604 100644 --- a/src/regexp/regexp-utils.cc +++ b/src/regexp/regexp-utils.cc @@ -36,7 +36,7 @@ Handle<String> RegExpUtils::GenericCaptureGetter( namespace { -V8_INLINE bool HasInitialRegExpMap(Isolate* isolate, Handle<JSReceiver> recv) { +V8_INLINE bool HasInitialRegExpMap(Isolate* isolate, JSReceiver* recv) { return recv->map() == isolate->regexp_function()->initial_map(); } @@ -47,7 +47,7 @@ MaybeHandle<Object> RegExpUtils::SetLastIndex(Isolate* isolate, uint64_t value) { Handle<Object> value_as_object = isolate->factory()->NewNumberFromInt64(value); - if (HasInitialRegExpMap(isolate, recv)) { + if (HasInitialRegExpMap(isolate, *recv)) { JSRegExp::cast(*recv)->set_last_index(*value_as_object, SKIP_WRITE_BARRIER); return recv; } else { @@ -59,7 +59,7 @@ MaybeHandle<Object> RegExpUtils::SetLastIndex(Isolate* isolate, MaybeHandle<Object> RegExpUtils::GetLastIndex(Isolate* isolate, Handle<JSReceiver> recv) { - if (HasInitialRegExpMap(isolate, recv)) { + if (HasInitialRegExpMap(isolate, *recv)) { return handle(JSRegExp::cast(*recv)->last_index(), isolate); } else { return Object::GetProperty(isolate, recv, @@ -147,9 +147,7 @@ bool RegExpUtils::IsUnmodifiedRegExp(Isolate* isolate, Handle<Object> obj) { JSReceiver* recv = JSReceiver::cast(*obj); - // Check the receiver's map. - Handle<JSFunction> regexp_function = isolate->regexp_function(); - if (recv->map() != regexp_function->initial_map()) return false; + if (!HasInitialRegExpMap(isolate, recv)) return false; // Check the receiver's prototype's map. Object* proto = recv->map()->prototype(); diff --git a/src/runtime/runtime-regexp.cc b/src/runtime/runtime-regexp.cc index 3e77bf1f..6c2f6d29 100644 --- a/src/runtime/runtime-regexp.cc +++ b/src/runtime/runtime-regexp.cc @@ -1295,10 +1295,9 @@ static Object* SearchRegExpMultiple(Isolate* isolate, Handle<String> subject, // doesn't properly call the underlying exec method. V8_WARN_UNUSED_RESULT MaybeHandle<String> RegExpReplace( Isolate* isolate, Handle<JSRegExp> regexp, Handle<String> string, - Handle<Object> replace_obj) { + Handle<String> replace) { // Functional fast-paths are dispatched directly by replace builtin. DCHECK(RegExpUtils::IsUnmodifiedRegExp(isolate, regexp)); - DCHECK(!replace_obj->IsCallable()); Factory* factory = isolate->factory(); @@ -1306,9 +1305,6 @@ V8_WARN_UNUSED_RESULT MaybeHandle<String> RegExpReplace( const bool global = (flags & JSRegExp::kGlobal) != 0; const bool sticky = (flags & JSRegExp::kSticky) != 0; - Handle<String> replace; - ASSIGN_RETURN_ON_EXCEPTION(isolate, replace, - Object::ToString(isolate, replace_obj), String); replace = String::Flatten(isolate, replace); Handle<RegExpMatchInfo> last_match_info = isolate->regexp_last_match_info(); @@ -1408,18 +1404,23 @@ RUNTIME_FUNCTION(Runtime_RegExpExecMultiple) { CONVERT_ARG_HANDLE_CHECKED(String, subject, 1); CONVERT_ARG_HANDLE_CHECKED(RegExpMatchInfo, last_match_info, 2); CONVERT_ARG_HANDLE_CHECKED(JSArray, result_array, 3); + + DCHECK(RegExpUtils::IsUnmodifiedRegExp(isolate, regexp)); CHECK(result_array->HasObjectElements()); subject = String::Flatten(isolate, subject); CHECK(regexp->GetFlags() & JSRegExp::kGlobal); + Object* result; if (regexp->CaptureCount() == 0) { - return SearchRegExpMultiple<false>(isolate, subject, regexp, - last_match_info, result_array); + result = SearchRegExpMultiple<false>(isolate, subject, regexp, + last_match_info, result_array); } else { - return SearchRegExpMultiple<true>(isolate, subject, regexp, last_match_info, - result_array); + result = SearchRegExpMultiple<true>(isolate, subject, regexp, + last_match_info, result_array); } + DCHECK(RegExpUtils::IsUnmodifiedRegExp(isolate, regexp)); + return result; } RUNTIME_FUNCTION(Runtime_StringReplaceNonGlobalRegExpWithFunction) { @@ -1736,14 +1737,6 @@ RUNTIME_FUNCTION(Runtime_RegExpReplace) { string = String::Flatten(isolate, string); - // Fast-path for unmodified JSRegExps. - if (RegExpUtils::IsUnmodifiedRegExp(isolate, recv)) { - RETURN_RESULT_OR_FAILURE( - isolate, RegExpReplace(isolate, Handle<JSRegExp>::cast(recv), string, - replace_obj)); - } - - const uint32_t length = string->length(); const bool functional_replace = replace_obj->IsCallable(); Handle<String> replace; @@ -1752,6 +1745,21 @@ RUNTIME_FUNCTION(Runtime_RegExpReplace) { Object::ToString(isolate, replace_obj)); } + // Fast-path for unmodified JSRegExps (and non-functional replace). + if (RegExpUtils::IsUnmodifiedRegExp(isolate, recv)) { + // We should never get here with functional replace because unmodified + // regexp and functional replace should be fully handled in CSA code. + CHECK(!functional_replace); + Handle<Object> result; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, result, + RegExpReplace(isolate, Handle<JSRegExp>::cast(recv), string, replace)); + DCHECK(RegExpUtils::IsUnmodifiedRegExp(isolate, recv)); + return *result; + } + + const uint32_t length = string->length(); + Handle<Object> global_obj; ASSIGN_RETURN_FAILURE_ON_EXCEPTION( isolate, global_obj, |