Bug 204479 - Fix broken String.prototype.replace() and replaceAll().
Summary: Fix broken String.prototype.replace() and replaceAll().
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: JavaScriptCore (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Mark Lam
URL:
Keywords: InRadar
Depends on:
Blocks: 204481
  Show dependency treegraph
 
Reported: 2019-11-21 16:29 PST by Mark Lam
Modified: 2019-11-21 18:17 PST (History)
9 users (show)

See Also:


Attachments
proposed patch. (18.18 KB, patch)
2019-11-21 16:44 PST, Mark Lam
ross.kirsling: review+
Details | Formatted Diff | Diff
patch for landing (includes rebased ChakraCore test results). (29.83 KB, patch)
2019-11-21 18:15 PST, Mark Lam
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Mark Lam 2019-11-21 16:29:39 PST
String.prototype.replace() regressed due to r252683: <https://trac.webkit.org/r252683> for webkit.org/b/202471.  The patch failed to handle InternalFunctions.

This patch also fixed a spec compliance bug for String.prototype.replace() i.e. the replaceValue needs to be evaluated before we check if there's a match in the source string.  See 21.1.3.14-9 at https://www.ecma-international.org/ecma-262/6.0/#sec-string.prototype.replace.

For String.prototype.replaceAll(), make sure it "behaves just like String.prototype.replace if searchValue is a global regular expression".  See https://github.com/tc39/proposal-string-replaceall.

<rdar://problem/57354854>
Comment 1 Mark Lam 2019-11-21 16:44:59 PST
Created attachment 384104 [details]
proposed patch.
Comment 2 Mark Lam 2019-11-21 16:50:01 PST
Comment on attachment 384104 [details]
proposed patch.

View in context: https://bugs.webkit.org/attachment.cgi?id=384104&action=review

> JSTests/stress/string-replaceAll-2.js:2
> +const supportsReplaceAll = (String.prototype.replaceAll != undefined);

FYI, I added this so that I can run this test on Chrome and Firefox as well to validate the test results.
Comment 3 Ross Kirsling 2019-11-21 17:19:53 PST
Comment on attachment 384104 [details]
proposed patch.

View in context: https://bugs.webkit.org/attachment.cgi?id=384104&action=review

It's a bit interesting that these tests fail silently in release, but I guess that's the sort of issue it is.

> Source/JavaScriptCore/ChangeLog:10
> +        String.prototype.replace() regressed due to r252683: <https://trac.webkit.org/r252683>
> +        for webkit.org/b/202471.  The patch failed to handle InternalFunctions.

Ugh, it seems that I underestimated the reason for the two huge branches in replaceUsingRegExpSearch. Sorry about that. :(

> Source/JavaScriptCore/ChangeLog:15
> +        This patch also fixed a spec compliance bug for String.prototype.replace() i.e.
> +        the replaceValue needs to be evaluated before we check if there's a match in the
> +        source string.
> +        Ref: 21.1.3.14-9 at https://www.ecma-international.org/ecma-262/6.0/#sec-string.prototype.replace

Oh, good catch! I guess there haven't been any tests for this.

BTW, this is now 21.1.3.17-6 in the living spec: https://tc39.es/ecma262/#sec-string.prototype.replace
Comment 4 Yusuke Suzuki 2019-11-21 17:25:02 PST
Comment on attachment 384104 [details]
proposed patch.

View in context: https://bugs.webkit.org/attachment.cgi?id=384104&action=review

r=me too

> Source/JavaScriptCore/ChangeLog:31
> +        Ref: https://bugs.webkit.org/show_bug.cgi?id=204481

Maybe, due to the reason why we have two functions, we should split it. String#replace is one of the most frequently used function.
Comment 5 Mark Lam 2019-11-21 17:27:13 PST
Comment on attachment 384104 [details]
proposed patch.

View in context: https://bugs.webkit.org/attachment.cgi?id=384104&action=review

>> Source/JavaScriptCore/ChangeLog:10
>> +        for webkit.org/b/202471.  The patch failed to handle InternalFunctions.
> 
> Ugh, it seems that I underestimated the reason for the two huge branches in replaceUsingRegExpSearch. Sorry about that. :(

The test that I just added will catch this from now on.

>> Source/JavaScriptCore/ChangeLog:15
>> +        Ref: 21.1.3.14-9 at https://www.ecma-international.org/ecma-262/6.0/#sec-string.prototype.replace
> 
> Oh, good catch! I guess there haven't been any tests for this.
> 
> BTW, this is now 21.1.3.17-6 in the living spec: https://tc39.es/ecma262/#sec-string.prototype.replace

Is the living spec constantly changing?  I'll stay with ecma-262/6.0 so that this ref doesn't go stale when the living spec changes again.  I think it's reasonable for the reader to look up a newer version if he/she wants it.

>> Source/JavaScriptCore/ChangeLog:31
>> +        Ref: https://bugs.webkit.org/show_bug.cgi?id=204481
> 
> Maybe, due to the reason why we have two functions, we should split it. String#replace is one of the most frequently used function.

I'll see what the microbenchmark says.
Comment 6 Mark Lam 2019-11-21 18:15:53 PST
Created attachment 384116 [details]
patch for landing (includes rebased ChakraCore test results).
Comment 7 Mark Lam 2019-11-21 18:17:44 PST
Landed in r252758: <http://trac.webkit.org/r252758>.